Меню сайта
Наш опрос
Оцените мой сайт
Всего ответов: 5
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Главная » 2014 » Июль » 22 » Работа со строками - что лучше Паскаль или C/С++?
15:25
Работа со строками - что лучше Паскаль или C/С++?
Если задача на олимпиаде требует работу со строками, то всегда возникают некоторые проблемы с оптимизацией и быстрой ее реализацией. Если вы знаете Паскаль и Си (С++), то что выбрать?В Паскале тип string работает как массив и хранит до 255 символов. Нумерация символов в строке начинается с 1. А в нулевом номере хранится символ, код которого отвечает за длину строки. В Си (точнее в С++) тоже есть тип string, но это класс и работать нужно со свойствами и методами этого класса.Ели строка длиннее 255 символов, то строку можно сохранить как массив символов типа char (как в Си). Но в Си строка символов - это указатель, т.е. адрес памяти, с которого начинается строка, а заканчивается строка символом с нулевым кодом или символом конца строки '\0' (и об этом нужно всегда помнить!). Если его нет, то при выводе может выйти весь мусор, который находится в памяти компьютера, до тех пор пока не найдется этот символ (соответствующий ему нулевой байт).Иногда по задаче даже не надо всю строку хранить, достаточно работать с одним символом типа char. В Си один символ заключается в апострофы, а строка - в кавычки. В Паскале - в любом случае - апострофом. Кроме этого в Си тип char - это целое со знаком в один байт, поэтому для русских букв (которые начинаются после 127 кода) при считывании получим отрицательный код. Чтобы этого избежать - объявляем как unsigned char.Существует проблема ввода/вывода русских символов в современных средах. Так в среде Lazarus используется кодировка UTF8, которая отводит 2 байта под один символ, а все функции со строками языка Паскаль в основном работают в кодировке ANSI, поэтому нужно в начале перевести строку с помощью функции utf8toansi в привычную для Паскаля кодировку. Та же проблема возникнет и в среде CodeBlocks при написании программ с русскими строками (даже при выводе). В этом случае можно поменять кодировку самого проекта или вставить функцию setlocale(LC_ALL,"Russian"). Не забудьте подключить библиотеку locale.h. Конечно можно написать свою функцию декодирования, но это займет время, которое очень дорого стоит во время олимпиады.Приведем стандартные алгоритмы при работе со строками, которые очень часто встречаются в олимпиадных задачах:Найти количество символов в строкеЗаменить символ в строкеУдалить символ в строке Переставить символы в строке наоборот Найти количество подстрок в строкеУдалить заданную строку d в строке sВставить заданную строку d в строку sЗаменить подстроку на заданную строкуВывести все слова в тексте, разделенные пробелом или иным символомВыделить цифры/число из строкиВывести число по заданному форматуОпределить дату/время по введенной строкеКаждая из этих задач по разному выполняется в Паскале и в Си. Если представить строку как массив символов, то разницы будет мало. Нужно сделать перебор каждого символа последовательно, как в массиве, если мы точно знаем сколько символов в строке. При этом ввод строки можно осуществить посимвольно. Если считывать всю строку, то в Паскале - это просто readln(s), а в Си - при потоковом вводе (с помощью cin) учитывается пробел, поэтому, если в строке есть пробелы, а нужно считать всю строку целиком, то используют специальную процедуру (например, getline). Но при этом конец строки не считывается, как в Паскале, его при выводе нужно добавлять самим (и об этом все время помнить!). Для определении количества символов обычно используют стандартные библиотеки: length(s) в Паскале, strlen(s) в С, s.length или s.size в С++.Кроме этого при работе с файлами есть свои заморочки: проверка конца строки (коду 10, а не 13 как для Enter, или EOLN), проверка конца файла (EOF).Описание строкПаскаль:var s:string; //строка с переменной длиной    a:string[100];//строка с максимальной длиной строки 100    b:array [1..500] of char;//массив из 500 символов    c:char; //один символС:unsigned char c; //один символ в кодировке ANSIchar ;//строка сразу заданаchar s[100]; // для строки выделяем 100 0'..'9'] then целое число - ' , x);{2 вариант}//выделяем из строки число, удаляя все не числовые символыreadln(s);repeatval(s,y,code);if code>0 then delete(s,code,1);//удаляем не числовой символuntil не всегда целое число - ' , y);//перевод числа x в строку sstr(x,s); шт. за '+a+' руб.';writeln(s);//одна цифра в 0')+6);//цифра как символ в 0');var hh,mm,ss,i,x:integer;//ввод и вывод времени hh:mm:ss или даты :',mm,':',ss);C:Для ввода и вывода строки нужно учитывать следующее: есть ли в строке пробелы и оканчивается ли строка после ввода символом конца строки.1) Можно считать как элементы массива и в конце добавить символ конца строки2) Используя формат для ввода и вывода строки "%s"3) Используя потоковый ввод и вывод для строки, содержащей пробелы#include <stdio.h>char , ;printf ("символы: %c %c %c\n", 'a', 65, c); printf ("строка: %s \n", t);scanf("%s",t); //считывает до первого пробелаscanf("%10s",t);//считает не более 10 символовscanf("%c",&c);//посимвольный ввод строкиint i; char s[20];for != '\n'; i++);  s[i] = '\0'; printf("\n%s\n", s);//ввод/вывод всей строки gets(s); //ввод строки с пробелами не включая нулевой символ '\0', длина считываемой строки не ограничена, поэтому, если выделено 20 строк, а введено более, то считает всю строку "куда-нибудь в память", что может привести к непредвиденным ситуациям.puts(s);//вывод строки с переходом на новую строку//ввод строки s с указанным максимально возможным размером size-1fgets(s, size, stdin);int k = strlen(s); // Длина строкиif((k > 0) && (s[k-1] \0';}/*Функция fgets() имеет побочный эффект. Кроме полезной информации, что была набрана с клавиатуры, в конец строки будет помещён символ с кодом 10, а только затем символ с кодом 0. Для каких-то задач это не существенно, но лучше всегда удалять этот "мусор": в позицию символа с кодом 10 записывать %d", i); // Записать в str строковое представление isscanf(str, "%d", &j); // Записать в j число, содержащееся в строке str sprintf(str, , i, j); // содержимое str: //преобразование из строки в числоdouble 23.4"); int 123"); long 100000000"); //Заполняем s символьной строкой "ABCD". После выхода из цикла переменная i равна 4. // В эту позицию и записываем нуль-символ.char s[6];int i;for(i = 0; i < 4; i++)s[i] = i + ;С++:cin >>a; //ввод слова до пробела int i, длина строки: "<<a<<"\n равна "<<l<<" или "<<a.length()<<endl;for Enter price: "; getline (cin,mystr);stringstream(mystr) >> price;cout << "Enter quantity: "; getline (cin,mystr);stringstream(mystr) >> quantity;cout << "Total price: " << price*quantity << endl;double ;//перевод из строки dd в число bbstringstream(dd)>>bb;cout<<'\n'<<bb;//перевод из строки ss в число aaistringstream ins;ins.str(ss);ins>>aa;cout<<'\n'<<aa;//перевод из числа bb в строку введите время по формату час:мин:сек -> ";cin >>hh>>c>>mm>>c>>ss;cout<<hh<<'-'<<mm<<'-'<<ss<<endl;cout<<"введите дату по формату день/месяц/год:";cin >>d>>c>>m>>c>>y;cout<<d<<'-'<<m<<'-'<<y<<endl;Работа с текстовыми файламиПаскаль:Var f:text; assign(f,'input.txt');reset(f);readln(f,s);close(f);assign(f,'output.txt');rewrite(f);writeln(f,s);close(f);//стандартный ввод/выводassign(input,'input.txt');reset(input); //если закоментировать, то ввод с клавиатуры,assign(output,'output.txt');rewrite(output);// а вывод на экранreadln(s);//input и output не объявляем и не упоминаем в командах!writeln(s);В среде Lazarus:вместо text используют textfileвместо assign используют assigntfileвместо close используют closefileС:FILE output.txt", He удается открыть файл.\n");  exit(1); } fprintf(f, "%s", input.txt","r");//открыть файл для чтенияfscanf(f, "%s", s);freopen("input.txt","r",stdin); //стандартный поток ввода/выводаfreopen("output.txt","w",stdout);  scanf("%s",s); printf("%c",c);//чтение одного символа из example.txt"); if (myfile.is_open()) { myfile << "This is a line.\n"; myfile << "This is another line.\n"; myfile.close(); } else cout << "Unable to open file"; //ввод строк из файла ifstream myfile ("example.txt");if (myfile.is_open()) {while ( myfile.good() ) { getline (myfile,lines); cout << lines << endl; } myfile.close(); }elsecout << "Unable to open file";//посимвольный ввод и вывод из файла пока не обнаружится конец файла EOFifstream in("input.txt");ofstream out("output.txt");while ( B';u = strchr(s, c);// Результатам выполнения функции strchr() будет адрес первого символа в строке s, который равен искомому символу c. Если символ не найден, то в указатель u будет записано число 0.u = strrchr(s, c);//Вычисляется адрес последнего вхождения символа c в строку s (т.е. справа или с конца const"); - вставка подстроки "const" в строку a с позиции indexstring b("moroz"); - инициализация строки +b+", "+b+"!"; - конкатенация (слияние) двух строкa.replace(index,count,b); - замена count символов на подстроку, начиная с позиции ok" int n;
Просмотров: 434 | Добавил: admin | Рейтинг: 0.0/0
Всего комментариев: 0
avatar
Форма входа
Календарь
«  Июль 2014  »
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
28293031
Архив записей