Этот блог посвящен вопросам подготовки к олимпиадам по программированию и самой технологии программирования. Используемый язык программирования предпочитаю Паскаль. С некоторых пор стала подробнее изучать Си, так что теперь могу поделиться примерами и на Си. Не все мне известно, но то, что знаю - делюсь с Вами.
Поиск по этому блогу
Показаны сообщения с ярлыком строки. Показать все сообщения
Показаны сообщения с ярлыком строки. Показать все сообщения
суббота, 5 октября 2019 г.
вторник, 23 апреля 2019 г.
Перевод числа в строку и наоборот в С++
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
string s="12";
istringstream in_str;
in_str.str(s);
int k;
in_str >> k;
cout<<k*2<< endl;
ostringstream out_str;
int N = 123;
out_str << N;
s = out_str.str()+" year";
cout<<s;
out_str.str(""); // clear stringstream
}
#include <sstream>
using namespace std;
int main()
{
string s="12";
istringstream in_str;
in_str.str(s);
int k;
in_str >> k;
cout<<k*2<< endl;
ostringstream out_str;
int N = 123;
out_str << N;
s = out_str.str()+" year";
cout<<s;
out_str.str(""); // clear stringstream
}
суббота, 30 апреля 2016 г.
Стек и очередь в Си
В языке Си (не С++) нет таких конструкций как класс и соответственно нет класса для работы с очередью и стеком. Но есть тип struct (структура), которая похожа на тип class, но без возможности включения методов (функций) в него. С помощью структуры можно описать все динамические структуры: стек, очередь, дек, списки, деревья.
В Си для выделения динамической памяти используется функция malloc, а для освобождения - функция free. В С++ для этих целей используется оператор new и delete соответственно.
Рассмотрим следующую задачу:
Дан набор числовых и символьных величин. Все числа целые, а символ всегда один. Символы и числа разделены одним пробелом. Необходимо вывести числа в обратном порядке, а символы - как они поступали на вход, т.е. в прямом порядке.
В этой задаче сформулируем несколько алгоритмических проблем:
- Как прочитать все данные, где будет конец ввода?
- Как отделить числа от символов? А если число состоит из нескольких цифр или оно отрицательное?
- Как вывести в обратном и прямом порядке? Какие динамические структуры нам в этом помогут?
1. Как прочитать все данные, где будет конец ввода?
В задаче не указано, когда закончиться набор данных, но можно предположить, что данные могут храниться в файле. Тогда считываем данные до конца файла (код конца файла можно определить с помощью функции EOF()). А если этот ввод производить с клавиатуры - то можно ввести код конца файла Ctrk+Z и Enter.
В более простом случае - можно вводить только строку. Тогда кодом конца строки будет символы с кодом 10 и 13, и на клавиатуре - это клавиша Enter. Для такой реализации можно в цикле while считывать символы последовательно до тех пор, пока символы с кодом 10 и 13 не обнаружатся. А можно просто считать всю строку с помощью функции gets(адрес начала строки) и далее в цикле for просматривать все символы последовательно до полученной длины строки.
2. Как отделить числа от символов? А если число состоит из нескольких цифр или оно отрицательное?
В более простом случае - можно вводить только строку. Тогда кодом конца строки будет символы с кодом 10 и 13, и на клавиатуре - это клавиша Enter. Для такой реализации можно в цикле while считывать символы последовательно до тех пор, пока символы с кодом 10 и 13 не обнаружатся. А можно просто считать всю строку с помощью функции gets(адрес начала строки) и далее в цикле for просматривать все символы последовательно до полученной длины строки.
2. Как отделить числа от символов? А если число состоит из нескольких цифр или оно отрицательное?
В этом случае посимвольное чтение символов должно сопровождаться проверкой, что:
- первый символ может быть минусом, после которого стоит любая цифра;
- цифра - это символ, который принадлежит диапазону от '0' до '9';
- после числа стоит один пробел.
Все эти условия можно проверить последовательно, используя некий флаг - переменная отвечающая за то, что мы считываем число, и "собирать" в числовую строку, которую потом с помощью функции atoi можно преобразовать в целый тип. Если флаг нулевой, то это не число. Важно после цикла проверить этот флаг, так как может оказаться, что последним был введен не символ, а число. И необходимо его сохранить.
3. Как вывести в обратном и прямом порядке? Какие динамические структуры нам в этом помогут?
Если нужно вывести в обратном порядке, то это стек, а если в прямом, то - очередь.
Реализация стека:
Опишем структуру (struct) данных, которая содержит информационную часть (то, что хранится в стеке) и указатель (адрес ячейки) на следующий элемент в стеке.
struct STACK
{
int a;
struct STACK *next;
};
{
int a;
struct STACK *next;
};
Кроме этого нужна переменная - указатель на начало (верхушка) стека. В начале программы указатель ни на что не указывает и имеет нулевой адрес NULL.
struct STACK *top=NULL;
Напишем два метода (функции): добавить/затолкать элемент (push) и удалить/вытолкнуть (pop) элемент.
void push(int c, struct STACK **b)
{
struct STACK *temp = (struct STACK*) malloc(sizeof(struct STACK));
struct STACK *temp = (struct STACK*) malloc(sizeof(struct STACK));
temp->a = c;
temp->next = (*b);
(*b) = temp;
}
Удаление элемента из стека:
int pop(struct STACK **t)
{
if ((*t)!=NULL)
{
struct STACK *temp=(*t);
int a = (*t)->a;
(*t) = (*t)->next;
free(temp);
return a;
}
else
return 0;
}
temp->next = (*b);
(*b) = temp;
}
Удаление элемента из стека:
int pop(struct STACK **t)
{
if ((*t)!=NULL)
{
struct STACK *temp=(*t);
int a = (*t)->a;
(*t) = (*t)->next;
free(temp);
return a;
}
else
return 0;
}
Реализация очереди:
Опишем структуру (struct) данных, которая содержит информационную часть (то, что хранится в очереди) и указатель (адрес ячейки) на следующий элемент в очереди.
struct QUEUE
{
char a;
struct QUEUE *next;
};
Кроме этого нужны две переменные - указатель на начало (голова) очереди и конец (хвост) очереди. В начале программы указатели ни на что не указывают и имеют нулевой адрес NULL.
struct QUEUE *head=NULL, *tail=NULL;
Напишем два метода (функции): добавить/затолкать элемент в конец очереди (push_back) и удалить/вытолкнуть элемент из начала очереди (pop_front).
Поставить в очередь:
struct QUEUE
{
char a;
struct QUEUE *next;
};
Кроме этого нужны две переменные - указатель на начало (голова) очереди и конец (хвост) очереди. В начале программы указатели ни на что не указывают и имеют нулевой адрес NULL.
struct QUEUE *head=NULL, *tail=NULL;
Напишем два метода (функции): добавить/затолкать элемент в конец очереди (push_back) и удалить/вытолкнуть элемент из начала очереди (pop_front).
Поставить в очередь:
![]() | ![]() |
![]() |
void push_back(char c, struct QUEUE **b)
{
if((*b)!=NULL)
{
struct QUEUE *temp=(struct QUEUE*) malloc(sizeof(struct QUEUE));
temp->a = c;
temp->next = NULL;
(*b)->n=temp;
(*b)=temp;
}
else
{
(*b) = (struct QUEUE*) malloc(sizeof(struct QUEUE));
(*b)->a = c;
(*b)->next = NULL;
head=(*b);
}
}
Удалить из очереди:
char pop_front(struct QUEUE **t)
{
if ((*t)!=NULL)
{
struct QUEUE *temp=(*t);
char a = (*t)->a;
(*t) = (*t)->next;
free(temp);
return a;
}
else
return 0;
}
{
struct QUEUE *temp=(*t);
char a = (*t)->a;
(*t) = (*t)->next;
free(temp);
return a;
}
else
return 0;
}
while(head!=NULL)
printf("%c ", pop_front(&head));
while(top!=NULL)
printf("%d ", pop(&top));
printf("%c ", pop_front(&head));
while(top!=NULL)
printf("%d ", pop(&top));
Приведем полный код программы:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
struct STACK
{
int a;
struct STACK *next;
#include <stdlib.h>
#include <stdio.h>
struct STACK
{
int a;
struct STACK *next;
};
struct STACK *top=NULL;
void push(int c, struct STACK **b)
struct STACK *top=NULL;
void push(int c, struct STACK **b)
{
struct STACK *temp = (struct STACK*) malloc(sizeof(struct STACK));
struct STACK *temp = (struct STACK*) malloc(sizeof(struct STACK));
temp->a = c;
temp->next = (*b);
(*b)=temp;
}
int pop(struct STACK **t)
temp->next = (*b);
(*b)=temp;
}
int pop(struct STACK **t)
{
if ((*t)!=NULL)
{
struct STACK *temp=(*t);
if ((*t)!=NULL)
{
struct STACK *temp=(*t);
int a = (*t)->a;
(*t) = (*t)->next;
free(temp);
return a;
}
else
return 0;
}
struct QUEUE
{
char a;
struct QUEUE *next;
(*t) = (*t)->next;
free(temp);
return a;
}
else
return 0;
}
struct QUEUE
{
char a;
struct QUEUE *next;
};
struct QUEUE *head=NULL, *tail=NULL;
void push_back(char c, struct QUEUE **b)
struct QUEUE *head=NULL, *tail=NULL;
void push_back(char c, struct QUEUE **b)
{
if((*b)!=NULL)
{
struct QUEUE *temp=(struct QUEUE*) malloc(sizeof(struct QUEUE));
if((*b)!=NULL)
{
struct QUEUE *temp=(struct QUEUE*) malloc(sizeof(struct QUEUE));
temp->a = c;
temp->next = NULL;
(*b)->next=temp;
(*b)=temp;
}
else
{
(*b) = (struct QUEUE*) malloc(sizeof(struct QUEUE));
(*b)->a = c;
(*b)->next = NULL;
head=(*b);
}
}
char pop_front(struct QUEUE **t)
temp->next = NULL;
(*b)->next=temp;
(*b)=temp;
}
else
{
(*b) = (struct QUEUE*) malloc(sizeof(struct QUEUE));
(*b)->a = c;
(*b)->next = NULL;
head=(*b);
}
}
char pop_front(struct QUEUE **t)
{
if ((*t)!=NULL)
{
struct QUEUE *temp=(*t);
if ((*t)!=NULL)
{
struct QUEUE *temp=(*t);
char a = (*t)->a;
(*t) = (*t)->next;
free(temp);
return a;
}
else
return 0;
}
int main()
{
char c[200], str[10];
gets(c);
int a, k=0;
for (int i=0; i<strlen(c); i++)
{
if (c[i]=='-' && c[i+1]>='0' && c[i+1]<='9' && k==0) k=1;
else
if (c[i]>='0' && c[i]<='9') k=1;
else
if (c[i]==' ' && k==1)
{
k=0;
strncpy(str,c,i+1);
strcpy(c,&(c[i+1]));
i=-1;
a=atoi(str);
push(a,&top);
}
else
{
if (c[i]!=' ') push_back(c[i], &tail);
strcpy(c,&(c[i+1]));
i=-1;
}
}
if(k==1)
{
a=atoi(c);
push(a,&top);
}
while(head!=NULL)
printf("%c ", pop_front(&head));
while(top!=NULL)
printf("%d ", pop(&top));
return 0;
}
(*t) = (*t)->next;
free(temp);
return a;
}
else
return 0;
}
int main()
{
char c[200], str[10];
gets(c);
int a, k=0;
for (int i=0; i<strlen(c); i++)
{
if (c[i]=='-' && c[i+1]>='0' && c[i+1]<='9' && k==0) k=1;
else
if (c[i]>='0' && c[i]<='9') k=1;
else
if (c[i]==' ' && k==1)
{
k=0;
strncpy(str,c,i+1);
strcpy(c,&(c[i+1]));
i=-1;
a=atoi(str);
push(a,&top);
}
else
{
if (c[i]!=' ') push_back(c[i], &tail);
strcpy(c,&(c[i+1]));
i=-1;
}
}
if(k==1)
{
a=atoi(c);
push(a,&top);
}
while(head!=NULL)
printf("%c ", pop_front(&head));
while(top!=NULL)
printf("%d ", pop(&top));
return 0;
}
четверг, 30 апреля 2015 г.
Задание 27(С4) с пробного ЕГЭ 2015 Вариант 2.
Задача:
5483
Пример выходных данных:
4
Примечание:
В этом примере исходное слово: АЕРАЕРР
кодовая двоичная последовательность: 110101101010
после добавления 1 справа получим: 1101011010101
Решение с рассуждениями:
1) Что нам по задаче дано: одно натуральное число N.
2) Что нужно получить: количество гласных букв в закодированном слове K (счетчик).
3) Сформулируем алгоритм решения: чтобы найти закодированные символы, нужно перевести число N в двоичную систему, перевернуть двоичное представление и удалить последний символ единицу. Затем сначала выделяем группы цифр и соотносим их с кодами символов. Символы сохраняем в строку и проверяем каждый символ в строке. Если это гласная буква, то увеличиваем счетчик.
Если реализовать этот алгоритм, то можете получить только 2 балла. Попробуем упростить наши действия.
4) Определим диапазон натурального числа: максимальное количество символов в слове 10, максимальное количество бит на кодирование символа - 2, получим 2*10+1=21 бит, т.е. 3 байта. Целое число без знака не менее 3 байт - это длинное целое, занимающее 4 байта.
5) Как будем хранить двоичное представление числа? В виде строки S или в массиве целых чисел A, длиной не менее 21.
6) Как перевести число в двоичное представление? Посмотрим на примере перевода числа 83:
83 : 2 = 41 целых 1 в остатке
41 : 2 = 20 целых 1 в остатке
20 : 2 = 10 целых 0 в остатке
10 : 2 = 5 целых 0 в остатке
5 : 2 = 2 целых 1 в остатке
2 : 2 = 1 целых 0 в остатке
1 : 2 = 0 целых 1 в остатке
Собираем с конца -1010011 и переворачиваем - 1100101. Запишем алгоритм так:
пока N не равно 0 делать
сохраняем остаток от деления N на 2
заменяем N на результат целочисленного деления N на 2
конец цикла пока
7) Видно, что переворачивать строку или массив не нужно. Так, если мы последовательно будем находить остатки, то их сразу будем заносить в массив или добавлять в строку справа. Переводить число в символ также не обязательно - можно просто проверить остаток на 0 и добавить к строке символ '0' или '1' если это 1.
8) Кроме этого, можно заметить, что удаление единицы можно заменить условием на N>1 вместо N<>0.
9) Как будем выделять коды символов?
Заметим, что с нуля начинается только один символ Е. Если встретилась '1', то проверяем следующий символ. Если это '0', то - символ Р (10), иначе - А (11). Таким образом можно сразу увеличивать счетчик K при проверке этих условий.
Попробуем реализовать этот алгоритм на Паскале с использованием строки:
var N: longint; i, b, m, K:integer; S:string[20];
begin
readln(N);
K:=0; S:='';
while N>1 do begin
b:=N mod 2;
N:=N div 2;
if b=0 then S:=S+'0' else S:=S+'1';
end;
m:=length(S);
i:=1;
while i<=m do
if s[i]='0' then begin K:=K+1; i:=i+1; end
else
if s[i+1]='1' then begin K:=K+1; i:=i+2; end
else i:=i+2;
writeln(K);
end.
Программа на Паскале с использованием массива:
var N: longint; i, b, m, K:integer; A:array[1..20] of byte ;
begin
readln(N);
K:=0; i:=0;
while N>1 do begin
b:=N mod 2;
N:=N div 2;
i:=i+1;
A[i]:=b;
end;
m:=i;
i:=1;
while i<=m do
if A[i]=0 then begin K:=K+1; i:=i+1; end
else
if A[i+1]=1 then begin K:=K+1; i:=i+2; end
else i:=i+2;
writeln(K);
end.
Оба варианта тянут на 3 балла. Попробуем написать на 4 балла.
10) Заметим, что цифры 0 или 1 мы получаем последовательно и их же потом и проверяем последовательно. Тогда зачем их хранить в массиве/строке? Будем сразу находить остатки и проверять условие. Приведем программу на С++:
#include <iostream>
using namespace std;
int main()
{
int N, K=0, b;
cin>>N;
while (N>1)
{
b=N%2;
N=N/2;
if (b==0) K++;
else
if (N%2==1)
{
K++;
N=N/2;
}
}
cout<<K;
return 0;
}
По каналу связи передается последовательность слов в алфавите {А, Е, Р}. Длина каждого слова не превосходит 10 букв, слова могут не быть осмысленными словами русского языка. Каждое слово передается в виде целого числа, полученного следующим образом:
1. Сначала слово кодируется с помощью неравномерного двоичного кода с кодовыми словами: Е - 0; Р - 10; А - 11.
2. К полученной двоичной последовательности b0b1...bm (длина последовательности - m+1) справа приписывается еще одна цифра bm+1 = 1;
3. Искомое число N вычисляется по формуле:
N = b0 + 21 · b1 + 22 · b2 + ... + 2m · bm + 2m+1 · bm+1.
Например, символьная последовательность ААЕЕР будет преобразована в 11110010, затем в 111100101, а затем - в число: 1 + 2 + 4 + 8 + 64 + 256 = 335. Отметим, что 335 = 1010011112.
Напишите программу, которая, получив на вход натуральное число, определяет, сколько раз в исходном слове встречаются гласные буквы, и выводит полученное значение на экран. Само слово выводить не нужно.
Пример входных данных:5483
Пример выходных данных:
4
Примечание:
В этом примере исходное слово: АЕРАЕРР
кодовая двоичная последовательность: 110101101010
после добавления 1 справа получим: 1101011010101
Решение с рассуждениями:
1) Что нам по задаче дано: одно натуральное число N.
2) Что нужно получить: количество гласных букв в закодированном слове K (счетчик).
3) Сформулируем алгоритм решения: чтобы найти закодированные символы, нужно перевести число N в двоичную систему, перевернуть двоичное представление и удалить последний символ единицу. Затем сначала выделяем группы цифр и соотносим их с кодами символов. Символы сохраняем в строку и проверяем каждый символ в строке. Если это гласная буква, то увеличиваем счетчик.
Если реализовать этот алгоритм, то можете получить только 2 балла. Попробуем упростить наши действия.
4) Определим диапазон натурального числа: максимальное количество символов в слове 10, максимальное количество бит на кодирование символа - 2, получим 2*10+1=21 бит, т.е. 3 байта. Целое число без знака не менее 3 байт - это длинное целое, занимающее 4 байта.
5) Как будем хранить двоичное представление числа? В виде строки S или в массиве целых чисел A, длиной не менее 21.
6) Как перевести число в двоичное представление? Посмотрим на примере перевода числа 83:
83 : 2 = 41 целых 1 в остатке
41 : 2 = 20 целых 1 в остатке
20 : 2 = 10 целых 0 в остатке
10 : 2 = 5 целых 0 в остатке
5 : 2 = 2 целых 1 в остатке
2 : 2 = 1 целых 0 в остатке
1 : 2 = 0 целых 1 в остатке
Собираем с конца -1010011 и переворачиваем - 1100101. Запишем алгоритм так:
пока N не равно 0 делать
сохраняем остаток от деления N на 2
заменяем N на результат целочисленного деления N на 2
конец цикла пока
7) Видно, что переворачивать строку или массив не нужно. Так, если мы последовательно будем находить остатки, то их сразу будем заносить в массив или добавлять в строку справа. Переводить число в символ также не обязательно - можно просто проверить остаток на 0 и добавить к строке символ '0' или '1' если это 1.
8) Кроме этого, можно заметить, что удаление единицы можно заменить условием на N>1 вместо N<>0.
9) Как будем выделять коды символов?
Заметим, что с нуля начинается только один символ Е. Если встретилась '1', то проверяем следующий символ. Если это '0', то - символ Р (10), иначе - А (11). Таким образом можно сразу увеличивать счетчик K при проверке этих условий.
Попробуем реализовать этот алгоритм на Паскале с использованием строки:
var N: longint; i, b, m, K:integer; S:string[20];
begin
readln(N);
K:=0; S:='';
while N>1 do begin
b:=N mod 2;
N:=N div 2;
if b=0 then S:=S+'0' else S:=S+'1';
end;
m:=length(S);
i:=1;
while i<=m do
if s[i]='0' then begin K:=K+1; i:=i+1; end
else
if s[i+1]='1' then begin K:=K+1; i:=i+2; end
else i:=i+2;
writeln(K);
end.
Программа на Паскале с использованием массива:
var N: longint; i, b, m, K:integer; A:array[1..20] of byte ;
begin
readln(N);
K:=0; i:=0;
while N>1 do begin
b:=N mod 2;
N:=N div 2;
i:=i+1;
A[i]:=b;
end;
m:=i;
i:=1;
while i<=m do
if A[i]=0 then begin K:=K+1; i:=i+1; end
else
if A[i+1]=1 then begin K:=K+1; i:=i+2; end
else i:=i+2;
writeln(K);
end.
Оба варианта тянут на 3 балла. Попробуем написать на 4 балла.
10) Заметим, что цифры 0 или 1 мы получаем последовательно и их же потом и проверяем последовательно. Тогда зачем их хранить в массиве/строке? Будем сразу находить остатки и проверять условие. Приведем программу на С++:
#include <iostream>
using namespace std;
int main()
{
int N, K=0, b;
cin>>N;
while (N>1)
{
b=N%2;
N=N/2;
if (b==0) K++;
else
if (N%2==1)
{
K++;
N=N/2;
}
}
cout<<K;
return 0;
}
понедельник, 12 января 2015 г.
Перестановка букв
Задача:
Дано N - количество букв и сами буквы (можно через пробел). Вывести все слова длиной N (1<=N<=10), содержащие все буквы без повторений.
Решение:
Данная задача имеет N! слов.
1. Эти слова можно получить рекурсивно:
процедура Gen(k - количество букв в слове)
{
если длина слова меньше N, то
цикл с первой буквы и до последней
если буква еще не выбрана - добавляем к слову
вызов процедуры Gen(k+1)
удаляем букву из слова
конец цикла
иначе
вывод слова.
}
Этот вариант алгоритма выведет слова в алфавитном порядке.
Например:
АВС
АСВ
ВАС
ВСА
САВ
СВА
Пример программы на Паскале:
Var
S,F:string;
N:integer;
Procedure Gen ( K:integer );
Var I: integer;
Begin
If (Length(S)=N) Then
Writeln(S)
else
For I:=1 to N do
if pos(F[i], S)=0 then begin
S:=S+F[i];
Gen(K+1);
delete(S,K,1);
End;
End;
Begin
Readln (N);
Readln (F);
S:='';
Gen(1);
End.
2. А можно и по технологии динамического программирования без рекурсии:
берем первую букву и образуем одно слово
в цикле по k от 1 до n
скопируем все слова еще k раз
для каждого слова
в цикле по i от 1 до k+1
вставляем следующую букву на i-ое место
конец цикла по i
конец цикла по k
вывод всех слов.
Слова хранятся в массиве. Размер массива заранее не известен, но его можно вычислить по формуле n! В С++ для этих целей можно использовать класс vector.
Этот вариант алгоритма выведет слова не алфавитном порядке. Поэтому получившийся массив слов перед выводом нужно отсортировать.
Например:
k=1
скопировали 1 раз
А
А
вставили В на 1-е и на 2-е место
ВА
АВ
k=2
скопировали 2 раза
ВА
АВ
ВА
АВ
ВА
АВ
вставили С на 1-е, 2-е и 3-е место
СВА
САВ
ВСА
АСВ
ВАС
АВС
и т.д.
Дано N - количество букв и сами буквы (можно через пробел). Вывести все слова длиной N (1<=N<=10), содержащие все буквы без повторений.
Решение:
Данная задача имеет N! слов.
1. Эти слова можно получить рекурсивно:
процедура Gen(k - количество букв в слове)
{
если длина слова меньше N, то
цикл с первой буквы и до последней
если буква еще не выбрана - добавляем к слову
вызов процедуры Gen(k+1)
удаляем букву из слова
конец цикла
иначе
вывод слова.
}
Этот вариант алгоритма выведет слова в алфавитном порядке.
Например:
АВС
АСВ
ВАС
ВСА
САВ
СВА
Пример программы на Паскале:
Var
S,F:string;
N:integer;
Procedure Gen ( K:integer );
Var I: integer;
Begin
If (Length(S)=N) Then
Writeln(S)
else
For I:=1 to N do
if pos(F[i], S)=0 then begin
S:=S+F[i];
Gen(K+1);
delete(S,K,1);
End;
End;
Begin
Readln (N);
Readln (F);
S:='';
Gen(1);
End.
2. А можно и по технологии динамического программирования без рекурсии:
берем первую букву и образуем одно слово
в цикле по k от 1 до n
скопируем все слова еще k раз
для каждого слова
в цикле по i от 1 до k+1
вставляем следующую букву на i-ое место
конец цикла по i
конец цикла по k
вывод всех слов.
Слова хранятся в массиве. Размер массива заранее не известен, но его можно вычислить по формуле n! В С++ для этих целей можно использовать класс vector.
Этот вариант алгоритма выведет слова не алфавитном порядке. Поэтому получившийся массив слов перед выводом нужно отсортировать.
Например:
k=1
скопировали 1 раз
А
А
вставили В на 1-е и на 2-е место
ВА
АВ
k=2
скопировали 2 раза
ВА
АВ
ВА
АВ
ВА
АВ
вставили С на 1-е, 2-е и 3-е место
СВА
САВ
ВСА
АСВ
ВАС
АВС
и т.д.
Пример программы на С++:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n,k,m;
string c;
vector <string> A;
cin>>n;
cin>>c;
A.push_back(c);
k=1;
for (int i=1;i<n;i++)
{
cin>>c;
m=A.size();
for (int j=1;j<=k;j++)
for (int l=0; l<m;l++)
A.push_back(A[l]);
int p=0;
for (int j=0;j<=k;j++)
for (int l=0; l<m;l++)
{
A[p].insert(j,c);
p++;
}
k=k+1;
}
m=A.size();
sort(A.begin(), A.end());
for (int i=0;i<A.size();i++)
{
cout<<A[i]<<endl;
}
return 0;
}
понедельник, 13 октября 2014 г.
Перевод из строки в число и обратно в Си
Рекомендую простую процедуру перевода из числа в строку:
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
char c[10];
int n;
float f;
cin >> n;
sprintf (c, "%d", n);//целое число в строковый поток вывода по формату
cout << c << endl;
cin >> f;
sprintf (c, "%.5f", f);//вещественное число с 5 знаками после запятой
cout << c;
return 0;
}
Если нужно извлечь цифры из строки:
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
string s;
char c;
cin >> s;
int n = s.size(), k;
for(int i = 0; i < n; i++)
if (s[i] >= '0' && s[i] <= '9')
{
k = s[i] - '0'; //в цифру
cout << k;
c = k + '0'; //и обратно в символ
cout << c;
}
return 0;
}
return 0;
Если вы работали со string а нужно в какой-нибудь функции ссылку на char, то:
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
string s;
cin >> s;
char *c = new char [(s.size()+1)];
strcpy (c, s.c_str());
cout << c;
delete c;
return 0;
}
Для тех же операций в С++:
#include <string>
#include <iostream>
#include <sstream>
stringstream (str_d) >> a; cout << a << endl;
stringstream (str_i) >> b; cout << b << endl;
//перевод из строки в число - 2 вариант
istringstream inp_s;
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
char c[10];
int n;
float f;
cin >> n;
sprintf (c, "%d", n);//целое число в строковый поток вывода по формату
cout << c << endl;
cin >> f;
sprintf (c, "%.5f", f);//вещественное число с 5 знаками после запятой
cout << c;
return 0;
}
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
string s;
char c;
cin >> s;
int n = s.size(), k;
for(int i = 0; i < n; i++)
if (s[i] >= '0' && s[i] <= '9')
{
k = s[i] - '0'; //в цифру
cout << k;
c = k + '0'; //и обратно в символ
cout << c;
}
return 0;
}
Еще один вариант:
#include <string.h>
#include <iostream>
#include <stdio.h> //для функции sscanf
#include <stdlib.h> //для функций atoi, atof, atol, itoa, ltoa
using namespace std;
int main()
{
char str[10] = "65.45";
#include <string.h>
#include <iostream>
#include <stdio.h> //для функции sscanf
#include <stdlib.h> //для функций atoi, atof, atol, itoa, ltoa
using namespace std;
int main()
{
char str[10] = "65.45";
float x;
sscanf (str, "%f", &x);//вещественное число
cin >> str;
int i;
sscanf (str, "%d", &i);//целое число
cout << i <<" "<<x;
//преобразование из строки в число
double c = atof ("23.4");
int b = atoi ("123");
long a = atol ("100000000");
cout << a <<" " << b << " " << c << endl;
//преобразование из числа в строку с указанием системы счисления
itoa (b, str, 10); cout << "10:" << str << endl;
itoa (b, str, 2); cout << "2:" << str << endl;
itoa (b, str, 8); cout << "8:" << str << endl;
itoa (b, str, 16); cout << "16:" << str << endl;
itoa (b, str, 5); cout << "5:" << str << endl;
ltoa (a, str, 10); cout << "long:" << str << endl;
}
#include <string.h>
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
string s;
cin >> s;
char *c = new char [(s.size()+1)];
strcpy (c, s.c_str());
cout << c;
delete c;
return 0;
}
Для тех же операций в С++:
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
double a;
int b;
string str_d = "74326.46238", str_i = "123";
//перевод из строки в число - 1 вариант
int main()
{
double a;
int b;
string str_d = "74326.46238", str_i = "123";
//перевод из строки в число - 1 вариант
stringstream (str_d) >> a; cout << a << endl;
stringstream (str_i) >> b; cout << b << endl;
//перевод из строки в число - 2 вариант
istringstream inp_s;
inp_s.str("25.02 rub");
inp_s >> a;
cout << a << endl;
inp_s.str("3 of clock");
inp_s >> b;
cout << b << endl;
//перевод из числа в строку
ostringstream out_s;
inp_s >> a;
cout << a << endl;
inp_s.str("3 of clock");
inp_s >> b;
cout << b << endl;
//перевод из числа в строку
ostringstream out_s;
out_s.precision(3); //задаем точность - 3 знака после запятой
out_s << "double:" << a << "\nfixed:" << fixed << a << "\n";
cout << out_s.str();
out_s.str(""); //очистка предыдущего потока
out_s << b << " int\n";
string s = out_s.str(); //сохраняем как строку
cout << s;
return 0;
}
out_s << "double:" << a << "\nfixed:" << fixed << a << "\n";
cout << out_s.str();
out_s.str(""); //очистка предыдущего потока
out_s << b << " int\n";
string s = out_s.str(); //сохраняем как строку
cout << s;
return 0;
}
четверг, 19 сентября 2013 г.
Работа со строками - что лучше Паскаль или 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. Конечно можно написать свою функцию декодирования, но это займет время, которое очень дорого стоит во время олимпиады.
Приведем стандартные алгоритмы при работе со строками, которые очень часто встречаются в олимпиадных задачах:
var s:string; //строка с переменной длиной
a:string[100];//строка с максимальной длиной строки 100
b:array [1..500] of char;//массив из 500 символов
c:char; //один символ
С:
c=&d; // передаем указатель строки d переменной с.
char* t;//строка - указатель на первый символ.
C++:
string a;//описание строки а как экземпляр класса string
int k = strlen(s); // Длина строки
if((k > 0) && (s[k-1] == 10))
{
k--;
//преобразование из числа в строку
С++:cin >>a; //ввод слова до пробела
int i, l=a.size();//размер строки
cout<<"длина строки: "<<a<<"\n равна "<<l<<" или "<<a.length()<<endl;
for (i=0;i<l;i++) cout<<a[i]<<endl;//посимвольный вывод
//ввод и вывод всей строки вместе с пробелами до нажатия Enter
string line;
getline (cin, line);
cout << line << endl; //внимание! перевод строки не считывается.
//посимвольный ввод и вывод до нажатия клавиши Enter (код 10)
while ( (c=cin.get()) != 10)
cout.put(c);
cout<<endl;
// считываем только числа (нужна библиотека sstream)
freopen("input.txt","r",stdin); //стандартный поток ввода/вывода
c=fgetc(stdin);//из стандартного потока ввода данных
string lines;
ofstream myfile ("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(); }
else
cout << "Unable to open file";
l:=length(s)- длина строки s
p:=pos(s1,s) - позиция подстроки s1 в строке s - всегда первое вложение!
s1:=copy(s,index,count) - выделение из строки s подстроки длины count, начиная с позиции index
delete(s,index,count); - удаление из строки s подстроки длины count, начиная с позиции index
insert(p,s,index); - вставка подстроки p в строку s начиная с позиции index
С:
char *u;
strlen(s) - длина строки без нулевого символа
strcpy(d,s) - копирует строку s в d (при этом не добавляется знак конца строки )
strcpy(d,s,n) - копирует строку s в d c максимально возможным количеством символов n при копировании
strcat(d,s) - соединяет строки d и s и результат записывает в d (конец строки сохраняется)
strncat(d,s,n) - Добавить в конец строки d первые n символов из строки s
strcmp(d,s) - сравнивает две строки, если они равны, то возвращает 0, если d<s, то возвращает число <0, иначе число >0
char c = 'B';
u = strchr(s, c);// Результатам выполнения функции strchr() будет адрес первого символа в строке s, который равен искомому символу c. Если символ не найден, то в указатель u будет записано число 0.
В Паскале тип 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).
Кроме этого при работе с файлами есть свои заморочки: проверка конца строки (коду 10, а не 13 как для Enter, или EOLN), проверка конца файла (EOF).
Описание строк
Паскаль:var s:string; //строка с переменной длиной
a:string[100];//строка с максимальной длиной строки 100
b:array [1..500] of char;//массив из 500 символов
c:char; //один символ
С:
unsigned char c; //один символ в кодировке ANSI
char d[]="programs for school";//строка сразу задана
char s[100]; // для строки выделяем 100 символовchar d[]="programs for school";//строка сразу задана
c=&d; // передаем указатель строки d переменной с.
char* t;//строка - указатель на первый символ.
t=(char*) malloc(10);//выделяем память под 10 символов
free(t); //освобождение памяти
string a;//описание строки а как экземпляр класса string
char *c; /* указатель на начало строки, пока равен NULL (нулевой адрес, который ни на что не указывает)*/
с=new char [100]; /* теперь выделили для хранения строки 100 байт и с указывает на адрес начала строки.*/
delete c[]; //освобождение памяти
readln(s); //ввод строки s
writeln(s);//вывод строки s
ls:=ord(s[0]);//длина строки s
readln(a); //ввод строки a и только до 100 символов
writeln(a);//вывод строки a
la:=length(a);//длина строки a
l:=0;
while not eoln do begin //
read(c);//посимвольный ввод строки
inc(l);//длина строки (учтите, что символов в строке/массиве не более 500)
b[l]:=c;
end;
readln;//обязательно перейдите на следующую строку
for i:=1 to l do write(b[i]);//посимвольный вывод
writeln; //переход на новую строку
var x,code:integer;y:real;
// считываем только первое найденное число
{1 вариант}
s:='';//пустая строка
while not eoln do begin
read(c);
if c in ['0'..'9'] then s:=s+c //проверка на цифры
else break;
end;
val(s,x,code);//перевод из строки в число
if code=0 then write('целое число - ' , x);
{2 вариант}
//выделяем из строки число, удаляя все не числовые символы
readln(s);
repeat
val(s,y,code);
if code>0 then delete(s,code,1);//удаляем не числовой символ
until code=0;
write('не всегда целое число - ' , y);
//перевод числа x в строку s
str(x,s); str(y:0:2,a);
s:=s+' шт. за '+a+' руб.';
writeln(s);
//одна цифра в символ
x:=6;
c:=chr(ord('0')+6);
//цифра как символ в число
read(c);
x:=ord(c)-ord('0');
hh:=0;
for i:=1 to 2 do begin
read(c);
x:=ord(c)-ord('0');
hh:=hh*10*(i-1)+x;//собираем цифры в число
end;
s:='';
for i:=1 to 2 do begin
read(c);
s:=s+c;
end;
//подключите модуль system (работает в среде FreePascal, Lazarus)
//strtoint - функция перевода из строки в целое
//strtofloat - функция перевода из строки в вещественное
Для ввода и вывода строки нужно учитывать следующее: есть ли в строке пробелы и оканчивается ли строка после ввода символом конца строки.
1) Можно считать как элементы массива и в конце добавить символ конца строки
2) Используя формат для ввода и вывода строки "%s"
3) Используя потоковый ввод и вывод для строки, содержащей пробелы
gets(s); //ввод строки с пробелами не включая нулевой символ '\0', длина считываемой строки не ограничена, поэтому, если выделено 20 строк, а введено более, то считает всю строку "куда-нибудь в память", что может привести к непредвиденным ситуациям.
с=new char [100]; /* теперь выделили для хранения строки 100 байт и с указывает на адрес начала строки.*/
delete c[]; //освобождение памяти
Ввод и вывод строк. Определение длины строки.
Паскаль:readln(s); //ввод строки s
writeln(s);//вывод строки s
ls:=ord(s[0]);//длина строки s
writeln(a);//вывод строки a
la:=length(a);//длина строки a
l:=0;
while not eoln do begin //
read(c);//посимвольный ввод строки
inc(l);//длина строки (учтите, что символов в строке/массиве не более 500)
b[l]:=c;
end;
readln;//обязательно перейдите на следующую строку
for i:=1 to l do write(b[i]);//посимвольный вывод
writeln; //переход на новую строку
var x,code:integer;y:real;
// считываем только первое найденное число
{1 вариант}
s:='';//пустая строка
while not eoln do begin
read(c);
if c in ['0'..'9'] then s:=s+c //проверка на цифры
else break;
end;
val(s,x,code);//перевод из строки в число
if code=0 then write('целое число - ' , x);
{2 вариант}
//выделяем из строки число, удаляя все не числовые символы
readln(s);
repeat
val(s,y,code);
if code>0 then delete(s,code,1);//удаляем не числовой символ
until code=0;
write('не всегда целое число - ' , y);
//перевод числа x в строку s
str(x,s); str(y:0:2,a);
s:=s+' шт. за '+a+' руб.';
writeln(s);
//одна цифра в символ
x:=6;
c:=chr(ord('0')+6);
//цифра как символ в число
read(c);
x:=ord(c)-ord('0');
var hh,mm,ss,i,x:integer;
//ввод и вывод времени hh:mm:ss или даты dd.mm.yyyyhh:=0;
for i:=1 to 2 do begin
read(c);
x:=ord(c)-ord('0');
hh:=hh*10*(i-1)+x;//собираем цифры в число
end;
read(c);//пропускаем разделитель времени
s:='';
for i:=1 to 2 do begin
read(c);
s:=s+c;
end;
//подключите модуль system (работает в среде FreePascal, Lazarus)
//strtoint - функция перевода из строки в целое
//strtofloat - функция перевода из строки в вещественное
//inttostr - функция перевода из целого в строку
//floattostr - функция перевода из вещественного в строку
mm:=strtoint(s);
read(c);//пропускаем разделитель времени
readln(ss);//оставшееся число считываем как целое
writeln(hh,':',mm,':',ss);
C:
1) Можно считать как элементы массива и в конце добавить символ конца строки
2) Используя формат для ввода и вывода строки "%s"
3) Используя потоковый ввод и вывод для строки, содержащей пробелы
#include <stdio.h>
char с='5', t[]="school";
printf ("символы: %c %c %c\n", 'a', 65, c);
char с='5', t[]="school";
printf ("символы: %c %c %c\n", 'a', 65, c);
printf ("строка: %s \n", t);
scanf("%s",t); //считывает до первого пробела
scanf("%10s",t);//считает не более 10 символов
scanf("%c",&c);
//посимвольный ввод строки
int i;
int i;
char s[20];
for (i=0; (s[i] = getchar()) != '\n'; i++);
s[i] = '\0';
printf("\n%s\n", s);
//ввод/вывод всей строки
puts(s);//вывод строки с переходом на новую строку
//ввод строки s с указанным максимально возможным размером size-1
fgets(s, size, stdin);int k = strlen(s); // Длина строки
if((k > 0) && (s[k-1] == 10))
{
k--;
s[k] = '\0';}
/*Функция fgets() имеет побочный эффект. Кроме полезной информации, что была набрана с клавиатуры, в конец строки будет помещён символ с кодом 10, а только затем символ с кодом 0. Для каких-то задач это не существенно, но лучше всегда удалять этот "мусор": в позицию символа с кодом 10 записывать нуль-символ.*/
k=isalpha(c);//проверка того, что символ — латинская буква. Здесь k будет не равно 0, если в переменой c хранится символ — латинская буква, и равно 0 — в противном случае.
k=isdigit(c);//проверка того, что символ — это цифра. Результат — не 0, если в c находится символ цифры, и 0 — если это не так.
//преобразование из числа в строку
char str[50];
int i=15;
int i=15;
int j;
sprintf(str, "%d", i); // Записать в str строковое представление i
sscanf(str, "%d", &j); // Записать в j число, содержащееся в строке str
sprintf(str, "i=%d and j=%d", i, j); // содержимое str: "i=15 and j=15"
//преобразование из строки в число
double d=atof("23.4");
double d=atof("23.4");
int i=atoi("123");
long l=atol("100000000");
//Заполняем s символьной строкой "ABCD". После выхода из цикла переменная i равна 4.
// В эту позицию и записываем нуль-символ.
char s[6];
int i;
for(i = 0; i < 4; i++)
s[i] = i + 'A';
s[i]='\0';
int i;
for(i = 0; i < 4; i++)
s[i] = i + 'A';
s[i]='\0';
int i, l=a.size();//размер строки
cout<<"длина строки: "<<a<<"\n равна "<<l<<" или "<<a.length()<<endl;
for (i=0;i<l;i++) cout<<a[i]<<endl;//посимвольный вывод
//ввод и вывод всей строки вместе с пробелами до нажатия Enter
string line;
getline (cin, line);
cout << line << endl; //внимание! перевод строки не считывается.
//посимвольный ввод и вывод до нажатия клавиши Enter (код 10)
while ( (c=cin.get()) != 10)
cout.put(c);
cout<<endl;
// считываем только числа (нужна библиотека sstream)
string mystr; float price=0; int quantity=0;
cout << "Enter price: "; getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: "; getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
double aa=5.5123;
int bb=10;
string ss="74326.46238",dd="123";
//перевод из строки dd в число bb
stringstream(dd)>>bb;
cout<<'\n'<<bb;
//перевод из строки ss в число aa
istringstream ins;
ins.str(ss);
ins>>aa;
cout<<'\n'<<aa;
//перевод из числа bb в строку ss
bb=456;
ostringstream oss;
oss<<bb;
ss=oss.str();
cout<<endl<<ss;
//ввод и вывод времени и даты по формату
int mm, hh, ss, d, m, y;
cout<<"введите время по формату час:мин:сек -> ";
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);
cout << "Enter price: "; getline (cin,mystr);
stringstream(mystr) >> price;
cout << "Enter quantity: "; getline (cin,mystr);
stringstream(mystr) >> quantity;
cout << "Total price: " << price*quantity << endl;
double aa=5.5123;
int bb=10;
string ss="74326.46238",dd="123";
//перевод из строки dd в число bb
stringstream(dd)>>bb;
cout<<'\n'<<bb;
//перевод из строки ss в число aa
istringstream ins;
ins.str(ss);
ins>>aa;
cout<<'\n'<<aa;
//перевод из числа bb в строку ss
bb=456;
ostringstream oss;
oss<<bb;
ss=oss.str();
cout<<endl<<ss;
//ввод и вывод времени и даты по формату
int mm, hh, ss, d, m, y;
cout<<"введите время по формату час:мин:сек -> ";
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 *f; assign(output,'output.txt');rewrite(output);// а вывод на экран
readln(s);//input и output не объявляем и не упоминаем в командах!
writeln(s);
В среде Lazarus:
вместо text используют textfile
вместо assign используют assigntfile
вместо close используют closefile
С:
if((f=fopen("output.txt", "w"))==NULL) //открыть файл для записи
{
printf("He удается открыть файл.\n");
exit(1);
}
fprintf(f, "%s", s);
fclose(f);
f=fopen("input.txt","r");//открыть файл для чтения
fscanf(f, "%s", s);
freopen("output.txt","w",stdout);
scanf("%s",s);
printf("%c",c);
//чтение одного символа из файла
c=fgetc(f);c=fgetc(stdin);//из стандартного потока ввода данных
//вывод одного символа в файл
fputc(c,f);
fputc(c,stdout);//в стандартный поток вывода данных
fgets(s, n, f);//Чтение строки из файла f размером не более n-1
C++:
//вывод строк в файл string lines;
ofstream myfile ("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(); }
else
cout << "Unable to open file";
//посимвольный ввод и вывод из файла пока не обнаружится конец файла EOF
ifstream in("input.txt");
ifstream in("input.txt");
ofstream out("output.txt");
while ( (c=in.get()) != EOF)
cout.put(c);
cout<<endl;
while ( (c=in.get()) != EOF)
cout.put(c);
cout<<endl;
Стандартные библиотеки при работе со строками:
Паскаль:l:=length(s)- длина строки s
p:=pos(s1,s) - позиция подстроки s1 в строке s - всегда первое вложение!
s1:=copy(s,index,count) - выделение из строки s подстроки длины count, начиная с позиции index
delete(s,index,count); - удаление из строки s подстроки длины count, начиная с позиции index
insert(p,s,index); - вставка подстроки p в строку s начиная с позиции index
С:
char *u;
strlen(s) - длина строки без нулевого символа
strcpy(d,s) - копирует строку s в d (при этом не добавляется знак конца строки )
strcpy(d,s,n) - копирует строку s в d c максимально возможным количеством символов n при копировании
strcat(d,s) - соединяет строки d и s и результат записывает в d (конец строки сохраняется)
strncat(d,s,n) - Добавить в конец строки d первые n символов из строки s
strcmp(d,s) - сравнивает две строки, если они равны, то возвращает 0, если d<s, то возвращает число <0, иначе число >0
char c = 'B';
u = strchr(s, c);// Результатам выполнения функции strchr() будет адрес первого символа в строке s, который равен искомому символу c. Если символ не найден, то в указатель u будет записано число 0.
u = strrchr(s, c);//Вычисляется адрес последнего вхождения символа c в строку s (т.е. справа или с конца строки).
u=strstr(d,s) - поиск строки d в строке s; возвращает адрес на начало подстроки, если строка найдена, иначе NULL
С++:
При работе со строками обычно используют функции библиотеки string.h:
При работе со строками обычно используют функции библиотеки string.h:
l=a.size(); - длина строки
l=a.length();
a.insert(index,"const"); - вставка подстроки "const" в строку a с позиции index
string b("moroz"); - инициализация строки
a="oй, "+b+", "+b+"!"; - конкатенация (слияние) двух строк
a.replace(index,count,b); - замена count символов на подстроку, начиная с позиции index
b=a.substr(index, count); - выделение подстроки длиной count из строки а, начиная с позиции index
//удаление подстроки "ok"
int n;
while((n=a.find("ok"))!=-1) //пока символ есть
a="oй, "+b+", "+b+"!"; - конкатенация (слияние) двух строк
a.replace(index,count,b); - замена count символов на подстроку, начиная с позиции index
b=a.substr(index, count); - выделение подстроки длиной count из строки а, начиная с позиции index
//удаление подстроки "ok"
int n;
while((n=a.find("ok"))!=-1) //пока символ есть
{
a.erase(n,2);//удаляем с позиции n два символа
}
a.swap(b); - обмен строк
Более подробно смотрите о Си и С++.
a.erase(n,2);//удаляем с позиции n два символа
}
a.swap(b); - обмен строк
Более подробно смотрите о Си и С++.
Подписаться на:
Сообщения (Atom)





