Форум «Всё о Паскале» _ Задачи _ Вывод символов из текста
Автор: Kritic 7.01.2006 22:27
Всем привет! У меня вот огромные проблемы с одной задачей на работу с текстом. Звучит она следующим образом: вывести на экран из введенного текста только те символы, которые встречаются в тексте один раз. Вроде задача не очень сложная, но я недогоняю. Пожалуйста, помогите, мне она уже нужна на завтра! Вот что у меня получилось пока:
Код
Program Lab3; Uses Crt; const ni=255; var simb_freq: array [1..ni] of integer; i: byte; ascode,longtxt: integer; txt_val:string; begin clrscr; writeln('Vvedite, pojaluista, text: '); writeln; readln(txt_val); {writeln(length(txt_val));} i:=0; simb_freq[i]:=0; repeat simb_freq[i]:=i; i:=i+1; until ni<=i; longtxt:=length(txt_val); for i:=0 to longtxt do begin ascode:=ord(txt_val[i]); writeln(ascode:2); simb_freq[ascode]:=simb_freq[ascode]+1; {writeln(simb_freq[ascode]);} end; i:=0; repeat if simb_freq[i]=1 then writeln(chr(i)); i:=i+1; until ni<=i; readln; end.
ascode - хранение ASCII-кода текущего элемента строки, longtxt - длина текста, txt_val - сам текст,
Последний цикл тут совсем не нужен. Короче, у меня такие были соображения: вводим текст, потом получаем ASCII-кода текущего элемента текста, далее: 1 вариант - далее делаем выборку тех символов, которые встречаются более 1 раза и после уже отсортированные заносим в массив с последующим выводом. 2 вариант - получаем Аски-коды всех элементов строки, заносим их в массив, но так, как там будут многие символы прописываться по 2 и более раз, то поставить какой-нибудь счетчик, который бы следил за каждой ячейкой, чтобы после можно было при опросе элементов массива узнать, сколько раз туда прописывался символ и если это количество равно 1, то выводить на экран. Вот такие вот соображения(может быть весь глупые). Если что не понятно, то спрашивайте сразу. Мне уже завтра нужно нести решение, поэтому некогда тянуть время. Всем заранее спасибо за помощь!
Автор: volvo 7.01.2006 22:50
Kritic, все проще гораздо:
Var freq: array[char] of integer; i: integer; j: char; s: string;
begin write('text = '); readln(s); for i := 1 to length(s) do inc(freq[s[i]]);
for j := #0 to #255 do if freq[j] = 1 then write(j); end.
Автор: Kritic 7.01.2006 23:16
Спасибо огромное!!!
Автор: Kritic 8.01.2006 6:38
Volvo, объясни, пожалуйста,что делает реально Паскаль, когда выполняет данную программу? Что происходит, когда выполняется for i := 1 to length(s) do inc(freq[s[i]]);? Когда мы сравниваем элементы массива с 1, как я понял, то мы выводим, только те символы, которые встретились 1 раз, если с 2, то которые два раза встретились. Следовательно, вопрос: элементы массива freq[j] теперь хранят то число, сколько раз символы встретились в тексте? А почему? Объясни, пожалуйста, поподробнее, а то мне нужно иметь четкое представление того, что делает машина(просто задачу зашищать нужно будет).
И еще: программа работает корректно только 1 раз, то есть если я введу слово "просто", она выдаст буквы "прст", далее , при повторном выполнении(не выходя из нее) она начинает глючить, так как видно в массиве хранятся, информация прошлого, то есть если я далее ввожу слово "лук", она вместо "лук" выводит "лукпрст". Как вот от этого избавиться? Заранее безмерно благодарен!!!
Вот пока все, что у меня имеется:
Код
Program Lab3; Uses Crt; const nj=#255; var freq: array [#0..nj] of integer; i:integer; j,Buk:char; text:string; begin clrscr; writeln('Программа выводит из текста только те символы, которые в нем встретились 1 раз.'); writeln(& #39;____________________________________________________________________________ ___'); repeat writeln; writeln('Пожалуйста, введите текст: '); writeln; readln(text); freq[j]:=0; for i:=1 to length(text) do inc(freq[text[i]]); writeln; for j:=#0 to nj do begin if freq[j]=1 then write(j:2); end; writeln; writeln; writeln('Если хотите выйти, нажмите "0x".'); buk:=Readkey; until Buk='0'; end.
Автор: volvo 8.01.2006 13:27
Значит, так. Я дал тебе полностью работоспособную программу, которая будет выполняться на любом компиляторе Паскаля. Зачем ту ее перекроил по-своему? Смысл вот этого исправления ты мне можешь объяснить:
const nj = #255; var freq: array [#0..nj] of integer;
Ты просто потерял красивую программу, и приобрел корявую. Смысл-то от этого не изменился, но ЗАЧЕМ?
Цитата
что делает реально Паскаль, когда выполняет данную программу?
Проходит посимвольно по введенной строке, и для каждого символа строки увеличивает соответствующий ему элемент массива на 1 (для этого и используется индексация Char-ом, а не целым числом, как обычно; если использовать целое, придется делать дополнительные преобразования, а зачем, если можно проще?)...
Цитата
И еще: программа работает корректно только 1 раз, то есть если я введу слово "просто", она выдаст буквы "прст", далее , при повторном выполнении(не выходя из нее) она начинает глючить, так как видно в массиве хранятся, информация прошлого, то есть если я далее ввожу слово "лук", она вместо "лук" выводит "лукпрст". Как вот от этого избавиться?
Можешь убрать, она просто обнуляет один элемент массива, причем неизвестно какой...
Автор: Kritic 8.01.2006 14:34
Спасибо, за подсказку, я знал , что нужно очистить массив, но не не знал как. Программу я изменил из-за того, чтобы препод не заподозрил, что не я ее решил, поэтому я ее и искорявил.Прога заработала нормально, только хотелось бы еще уяснить один момент. Тот же пример с "просто": ввожу, выдает "прст", а после нажимаю два раза Enter, а он вместо пустой строки выдает "п". Почему? Что нужно сделать, чтобы он выдавал пустую строку, а не выводил какой-то левый символ(кстати, ты не знаешь, почему он именно его выводит?)? Извини, что такое большое кол-во вопросов, просто некогда самому уже разбирать!!! Спасибо за немалую помошь.