пятница, 23 марта 2012 г.

Некоторые секреты языков программирования

Есть задачи, которые можно достаточно быстро решить, зная особенности программирования на Паскале или Си.
Например, перевести число в римской системе счисления в десятичную. Известно, что римская система непозиционная и каждому символу соответствует одно и тоже значение:
M=1000
D=500
C=100
L=50
X=10
V=5
I=1
В зависимости от места в числе оно либо складывается либо вычитается: если число слева меньше стоящего рядом, то вычитается. Например, СМ = -100+1000=900.
Такого рода задачи решают либо через оператор выбора либо с помощью оператора условия. Данные хранятся в строковой переменной. Предлагаю другой вариант с помощью объявления массива с символьными индексами: var A:array['A'..'Z'] of integer;
Тогда при обращении к элементу массива с заданной буквой мы точно будем знать его значение в римской системе, т.е. A['M']:=1000, A['D']:=500 и т.д. Получим следующий код программы:
Var A:array['A'..'Z'] of integer; S:string; i,r:integer;
begin
readln(s);
A['M']:=1000;
A['D']:=500;
A['C']:=100;
A['L']:=50;
A['X']:=10;
A['V']:=5;
A['I']:=1;
r:=0;
for i:=1 to length(s)-1 do
if A[S[i]]<A[S[+1]] then r:=r-A[S[i]] else r:=r+A[S[i]];
r:=r+A[S[i+1]];
writeln(r);
end.
Все уместилось в один цикл.
Тоже самое можно сделать и в Си, так как символы в Си при считывании хранятся как байтовое его представление, то при работе с массивом достаточно указать количество символов в кодировочной таблице. Вот как будет выглядеть программа на Си:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int A[256],i,r=0,k; char s[100];
scanf("%s",&s);
A['M']=1000;
A['D']=500;
A['C']=100;
A['L']=50;
A['X']=10;
A['V']=5;
A['I']=1;
k=strlen(s);
for(i=0;i<k-1;i++)
{
if (A[s[i]]<A[s[i+1]]) r- = A[s[i]];
else r+ = A[s[i]];
}
r+ = A[s[k-1]];
printf("%d",r);
return 0;
}
Есть еще задача: вычислить частоту появления символов латинского языка (в %) в заданном тексте.
Var A:array['a'..'z'] of integer;
k,i:integer;
c:char;
begin
fillchar(A,sizeof(A),0);//инициализация массива
k:=0;
while not eof() do begin
read(c);
if c in ['a'..'z'] then begin A[c]:=A[c]+1;inc(k); end;
end;
for c:='a' to 'z' do if A[c]>0 then writeln(c,'-',A[c]/k*100:0:2);
end.
При этом сортировка в алфавитном порядке не нужна. Если нужно выводить в порядке убывания или возрастания частоты, то делаем сортировку, например, пузырек или любую другую.
Если учитывать заглавные символы, то нужно перевести все заглавные в строчные смещением на 32 в коде символа (известно, что в кодовой таблице заглавные символы отстоят от строчных ровно на 32 позиции): c:=chr(ord(c)+32); и в Си c+=32;
Точно также можно решить и другие похожие задачи, например, с числами или русскими буквами и пр.

В С++ есть удобный оператор ввода cin. С помощью него можно легко прочитать дату без перевода строки в число, учитываю точку как символ-разделитель:
#include <iostream.h>
#include <stdlib.h>
int main()
{
int day,month,year; char c;
cin>>day>>c>>month>>c>>year;//здесь символ с считывает точку
cout<<day<<"/"<<mounth<<"/"<<year;
return 0;
}
Для считывания времени символ-разделитель будет двоеточие.

Комментариев нет:

Отправить комментарий