2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Сортировка слов в строке.(на С)
Сообщение06.01.2013, 07:53 
Задание: Дана строка русских слов, разделенных одним или несколькими пробелами. Вывести на экран эти слова, разделенные одним пробелом и в алфавитном порядке.
Я смог удалить пробелы и перенести все слова в двумерный массив
код: [ скачать ] [ спрятать ]
Используется синтаксис C
void deletes(char *s, int pos)
{
        int i;
        if ((s[pos]== ' ') && (s[pos+1]== ' '))
        {      
                deletes(s,pos+1);
        }
        for (i = pos; i < strlen(s)-1; i++)
        {
                s[i]=s[i+1];
        }
        s[i]=0;

}

void main()
{
        setlocale(LC_ALL, "Russian");

        printf("Bведите строку: ");
        char s[CHAR_MAX];char strnew[CHAR_MAX][CHAR_MAX];
        gets(s);
        int count = 0;
        char *pstr;
        pstr = strtok(s," ");
        while (pstr != NULL) // подсчет количества слов
        {
                pstr=strtok(NULL," ");
                count++;
        }
        /*удаление лишних пробелов*/
        for (int i = 0; i < strlen(s); i++)
        {  if ((s[i]==' ') && (s[i+1]==' '))
                deletes(s,i+1);
        }
        /*перенос слов в новый массив для сравнения*/
        for (int j = 0, z = 0; j < count; j++)
        {
                for (int i = z, l = 0; s[i] != '\0' ; i++, l++)
                {
                        strnew[j][l] = s[i];
                        strnew[j][l + 1] = '\0';
                        z++;
                }
                z++;
        }                                    
        /*окончание переноса*/

А как вывести их в алфавитном порядке? и чтобы нормально с русским языком работало надо функцию OemToChar использовать?

 
 
 
 Re: Сортировка слов в строке.(на С)
Сообщение07.01.2013, 12:32 
я смог это решить
код: [ скачать ] [ спрятать ]
Используется синтаксис C
#include <stdio.h>
#include <conio.h>
#include <string>
#include <limits>
#include <locale>
#include <Windows.h>

void main()
{
        setlocale(LC_ALL, "Russian");
        printf("Введите строку: ");
        char s[CHAR_MAX];
        scanf("%[^\n]s", &s);
        OemToCharA(s,s);
        char strnew[CHAR_MAX][CHAR_MAX];
        int k = 0;
        int dl = strlen(s);
        for(int i = 0; i < dl; i++)
                if( s[i] != ' ')
                {
                        int j = 0;
                        for(j; s[i + j] != ' ' && s[i + j] != '\0'; j++)
                                strnew[k][j] = s[i + j];
                        strnew[k][j] = '\0';
                        k++;
                        i += j;
                }

                qsort(strnew, k, CHAR_MAX, (int (*)(const void *,const void *)) strcmp);

                for(int i = 0; i < k; i++)
                        printf("%s ", strnew[i]);
                _getch();
}

знающие люди подскажите, где улучшить это можно?

 
 
 
 Re: Сортировка слов в строке.(на С)
Сообщение07.01.2013, 15:52 
Так на C или C++?

 
 
 
 Re: Сортировка слов в строке.(на С)
Сообщение08.01.2013, 14:50 
Просто на С

 
 
 
 Re: Сортировка слов в строке.(на С)
Сообщение08.01.2013, 15:23 
Оказывается, qsort в C есть. :oops:

 
 
 
 Re: Сортировка слов в строке.(на С)
Сообщение08.01.2013, 19:59 
Я бы посоветовал а) использовать strcoll — избавляет от необходимости использовать OemToChar (плюс, что если вас заставят скомпилировать под FreeBSD/Linux?); б) использовал бы индексную сортировку, не раздергивая строку в новый массив строк; в) читал бы строку по-нормальному... не помню, увы, как это делается в Си...

 
 
 
 Re: Сортировка слов в строке.(на С)
Сообщение09.01.2013, 13:37 
вместо этого как я понял
Используется синтаксис C
 scanf("%[^\n]s", &s)

надо было это юзать
Используется синтаксис C
gets(s)

а как использовать индексную сортировку? просто в одной строке посимвольно до пробелов сравнивать или как?

 
 
 
 Re: Сортировка слов в строке.(на С)
Сообщение09.01.2013, 16:08 
Не используйте gets(char*). Ее в 2011 году наконец-то убрали из стандарта языка Си и добавили gets_s(char*, size_t). Кроме того, есть fgets(). У GNU (а значит, в BSD/Linux) есть замечательная функция getline() — увы, она нестандартна, под Windows вы ее вряд ли встретите. Так что можете перевоплотить ее сами: читаете в буфер, если он закончился — удлиняете и читаете дальше.

Индексная сортировка — заводите массив int *indices = (int*)malloc(sizeof(int) * starting_size) под индексы, где начинаются слова. Пробегаете по строке, заполняя этот массив и заменяя первый пробел в конце слова на '\0'. Да, скорее всего, indices тоже ручками придется удлинять. Теперь сортируете этот массив так, чтобы у вас было strcoll(&s[indices[i]], &s[indices[i+1]]) <= 0 для всех i, для которых это имеет смысл, после чего for(int i = 0; i < indices_count; i++) { printf("%s\n", &s[indices[i]]); }

Когда используете printf(), всегда, всегда печатайте строки с использованием "%s": даже простейшие printf("%s", "Error!"); — потому что иначе, при использовании printf(s), рано или поздно внутри s окажется процент — и вы испортите стек. Это очень больно.

Насчет setlocale: если вы пишете консольное приложение под Windows, стоит сказать setlocale(LC_ALL, ".OCP"), после чего strcoll(char*, char*) будет сравнивать строки именно в OEM-кодировке, и вам не нужно будет дергать OemToAnsi()/AnsiToOem() . Под FreeBSD/Linux, насколько я помню, работает setlocale(LC_ALL, NULL) — там нету шизофрении с OEM/ANSI кодировками. Кстати, вам на самом деле здесь LC_ALL не особо нужен, хватит и LC_COLLATE.

 
 
 
 Re: Сортировка слов в строке.(на С)
Сообщение09.01.2013, 17:07 
большое спасибо :-)

 
 
 [ Сообщений: 9 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group