Массив строк
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
Имеется строковый двумерный массив. Столкнулся с проблемой - а как отсортировать его по длине строк?
Если через strlen(), то это нужно менять строки местами в массиве, наверное. Это реально?
Если использовать strcpy то я по идее мог бы скопировать одну строку массива в темп, потом из темпа - в другую строку. Ну, пузырьком, в общем. Но то ли я дурак, то ли компилятор - не позволяет.
Есть ещё чудесная strcmp(), но более дву строк я за раз не сравню, так что бесполезно, наверное.
А теперь, вопрос - может кто-то сталкивался или видел, как кто-то сортирует такое? Или может алгоритм есть, а я не знаю?
Если через strlen(), то это нужно менять строки местами в массиве, наверное. Это реально?
Если использовать strcpy то я по идее мог бы скопировать одну строку массива в темп, потом из темпа - в другую строку. Ну, пузырьком, в общем. Но то ли я дурак, то ли компилятор - не позволяет.
Есть ещё чудесная strcmp(), но более дву строк я за раз не сравню, так что бесполезно, наверное.
А теперь, вопрос - может кто-то сталкивался или видел, как кто-то сортирует такое? Или может алгоритм есть, а я не знаю?
Ну разумеется тут не обойтись без другого такого же массива, если не хочется ломать мозг.
Ищешь в основном массиве самую длинную строку (strlen()), заносишь ее в другой массив на "последнее место" (в первой итерации цикла можно назвать "первым местом"), обнуляешь уже ненужную строку в основном. Все это в цикле, необходимые условия не составит труда придумать. И всеу. Если уж строго нужно, чтоб в основном массиве все это было сделано, то копируешь из второго в основной.
Ищешь в основном массиве самую длинную строку (strlen()), заносишь ее в другой массив на "последнее место" (в первой итерации цикла можно назвать "первым местом"), обнуляешь уже ненужную строку в основном. Все это в цикле, необходимые условия не составит труда придумать. И всеу. Если уж строго нужно, чтоб в основном массиве все это было сделано, то копируешь из второго в основной.
Код: Выделить всё
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int main()
{
char str[10][10];
int i=0;
for(i=0;getchar()!='*' ;)
{
fgets(str[i],10,stdin);
i++;
}
int k=i;
printf("/n%i",k);
for (i=0;i<k; i++)
printf("\n%s",str[i]);
char r[10]={0};
for (i=0; i<k-1; i++)
{
for (int j=i+1; j<k; j++)
{
if (strlen(str[i])<strlen(str[j]))
{
strcpy(r,str[i]);
strcpy(str[i],str[j]);
strcpy(str[j],r);
}
}
}
for (i=0;i<k; i++)
printf("%s\n",str[i]);
}
Я твою задачу так решил. Вводишь 10 слов, каждое может содержать 10 символов. Я проверки не писал, поэтому вводи придерживаясь этих правил. Причем имея ввиду то, что строка заканчивается нуль-символом, букв нужно вводить не более 9. Разумеется спрашивай, если что не понятно. Код смотри в вложении
- Вложения
-
[Расширение txt было запрещено, вложение больше недоступно.]
А чего ты не меняшь указатели местами. Это быстрее.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
#define while if
Оптимизация по размеру:
#define struct union
- Romeo
- Сообщения: 3126
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Airhand, ты не прав.
При задании массива строк в виде:
мы получаем массив константных указателей, так что указатели менять местами нельзя. И дело тут не во вредности компилятора, а в том, что при таком задании массив уже размещён на стеке и менять указатели в нём просто невозможно физически.
Для того, чтобы получилось менять указатели местами следует создавать массив строк динамически:
Однако при столь малых размерах самих строки и их количества, затраты на динамическое выделение памяти будут выше, чем затраты на копирование строк в случае выделения памяти на стеке, так что приведённый подход будет работать всё равно быстрее.
При задании массива строк в виде:
Код: Выделить всё
char str[10][10];
Для того, чтобы получилось менять указатели местами следует создавать массив строк динамически:
Код: Выделить всё
char** str = new char* [10];
for (int i = 0; i < 10; str[i++] = new char [10]);
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ммм, спасибо. Но всё-таки условие в данном случае необходимо. И, если будете писать ещё код - на анси си пожалуйста, если конечно вас не затруднит.
Вообще какие идеи насчёт условия? Что кроме гетчара может остановить ввод при получении в качестве аргумента пустой строки или другого редкого символа(горизонтальной табуляции например)?
Вообще какие идеи насчёт условия? Что кроме гетчара может остановить ввод при получении в качестве аргумента пустой строки или другого редкого символа(горизонтальной табуляции например)?
Я имел ввиду переделать исходник так, тобы можно было менять местами указатели.
Оптимизация по скорости:
#define while if
Оптимизация по размеру:
#define struct union
#define while if
Оптимизация по размеру:
#define struct union
Код: Выделить всё
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
int main()
{
char str[10][10];
int i=0;
while(!feof(stdin)&&i<10)
{
scanf("%s\n", str[i]);
i++;
}
int k=i;
printf("\n%i",k);
for (i=0;i<k; i++)
printf("\n%s",str[i]);
printf("\n\n");
char r[10]={0};
for (i=0; i<k-1; i++)
{
for (int j=i+1; j<k; j++)
{
if (strlen(str[i])<strlen(str[j]))
{
strcpy(r,str[i]);
strcpy(str[i],str[j]);
strcpy(str[j],r);
}
}
}
for (i=0;i<k; i++)
printf("\n%s",str[i]);
printf("\n");
}
Спасибо всем, кто откликнулся.
Мне кажется при увеличении массива по обеим размерностям код будет медленный. Имхо, для улучшения проще разок пробежаться по нему, построить массив размеров строк, его отсортировать (напрягая память вспоминаю стандартную qsort() чтобы ничего не выдумывать) и потом уж копировать. куча вызовов функций уйдёт.