Форум
» Назад на решение задач по физике и термеху
Регистрация | Профиль | Войти | Забытый пароль | Присутствующие | Справка | Поиск

» Добро пожаловать, Гость: Войти | Регистрация
    Форум
    Информационные технологии
        Решение задач на Pascal. Форум 2
Отметить все сообщения как прочитанные   [ Помощь ]
» Добро пожаловать на форум "Информационные технологии" «

Переход к теме
<< Назад Вперед >>
Несколько страниц [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 ]
Модераторы: paradise, KMA
  

KMA



Долгожитель

Перед тем, как отправить сообщение, обязательно просматривайте его содержимое, или хотя бы после того как отправили это сообщение посмотрите насколько правильно оно у вас отображается.

Если ваше сообщение не приемле (т. е. видны крякобразы, непонятные символы) или выделено курсивом то, что не требовалось, то все сообщения впредь удаляются модераторами. Поэтому у вас два выбора:
1) Пишите все так, как надо, т. е. по правилам и получаете помощь;
2) Либо, вообще ничего не пишите, т. к. Вас не удовлетворяют наши правила.

Всего сообщений: 940 | Присоединился: декабрь 2005 | Отправлено: 19 фев. 2008 17:32 | IP
ewgen



Новичок

пардон конечно, не обратил внимания, впредь буду внимательным. И всё же помогите мне с задачей: нужно все цифры в строке сложить если между ними '+' и вычесть если '-', буквы игнорировать, если идут две подряд цифры, то воспринимать их как 2-х значное число; вот мои наработки:
представил автомат, во 2-ое состояние вхожу если введены цифры иначе иду в 3-е(ошибка), далее остаюсь во втором если в строке цифра и перехожу в 4-ое если в строке'+' или в 5-ое если '-'. Из 4-ого и 5-ого перехожу обратно во 2-ое если текущий символ - цифра. currentNum - текущее значение,  result - сумма
begin
result:=0;
    currentNum:=0;
writeln('введите строку ');readln(st);
n:=length(st);
flag:=false;
s:=1;
while flag=true do
begin
case s of
        1: begin
        if  (st[ i ]='1') or   (st[ i ]='2') then s:=2
             currentNum:=val st[ i ];
             else s:=3; writeln('error');
           end;
        2: begin
        {currentNum:=val(st[ i ]);
             result:=result+currentNum;z}
         if  (st[ i ]='1') or   (st[ i ]='2') then s:=2;
         
          begin if(st[ i ]='+')   then s:= 4 end;
            begin if(st[ i ]='-')   then s:= 5 end ;
           end;        
        3:flag:=true;
  end;
 end;

end.


KMA: еще раз, повторяю, что записывать [ i ] надо только так (т. е. с пробелами по бокам). Иначе, это читается как выделить курсивом, и код уже хуже воспринимается.

(Сообщение отредактировал KMA 19 фев. 2008 23:52)

Всего сообщений: 6 | Присоединился: февраль 2008 | Отправлено: 19 фев. 2008 22:53 | IP
KMA



Долгожитель

Погоди, и чего ты добьешься своими переходами и автоматом? Давай я сделаю проще, может по времени это и займет больше, но суть от этого в принципе не поменяется.

Вначале уберем весь "мусор", т. е. все буквы, и ненужные нам символы.
В итоге у тебя получиться новая строка, красивая строка, вот функция, которая очищается строку от всякого мусора (я ее так и назвал, удалить мусор ):
Code Sample:
 
{возвращает строку содержащую только цифры и унарные операции сложения и вычитания}
function deleteTrash (st: string): string;
const number=['0'..'9'];
var i, j: byte;
   s: string;
Begin
    j:=0;
    s:='';
    for i:=1 to length(st) do
     if (st[ i ] in number) or (st[ i ] ='+') or (st[ i ] ='-')
        then
         begin
          inc(j);
          {копирует символ, если он "правильный"}
          s:=s+st[ i ]
         end;
    deleteTrash:=s
End;


В итоге, после применения этой процедуры, у тебя в строке не останется мусора, но остается не решенным вопрос о повторяющихся знаках (и о знаках в конце и начале). Как их удалить, смотри ниже (я оставляю последний знак, например, в последовательности знаков +--+--+, последний знак +, поэтому он и останется).
Code Sample:
 
function trimSingles(st:string): string;
var i: byte;
   s: string;
Begin
    //уберем знаки с конца
    i:=0;
    while (st[length(st)-i] in singles) and (i<=length(st)) do
     inc (i);
    st:=copy(st, 1, length(st)-i);
    //удаляем знаки с начала
    i:=1;
    while (st[ i ] in singles) and (i<=length(st)) do
     inc(i);
    if i=length(st) //если строка из знаков
       then trimSingles:=''
       else // если строка не из одних знаков
        begin
         s:='';
         while i<=length(st) do
          if (st[ i ] in singles) and (st [i+1] in singles)
             then  //проверяем на подряд идущие знаки
              begin
               //движемся пока не найдем конец знака
               inc(i);
               while (st[ i ] in singles) and (i<=length(st)) do
                inc (i);
               s:=s+st[i-1] //присвоим последний знак
              end
             else
              begin
               s:=s+st[ i ];
               inc(i)
              end;
         trimSingles:=s;
        end;
End;


Я конечно запихал константу number в const функции, однако, прошу, учти, что ее нужно вынести на уровень глобальных констант... и еще добавь такую константу: singles=['+', '-']; Тогда все будет работать.

Теперь смотри, в итоге, чтобы получить чистенькую и готовую к обработке строку нужно сделать так:
Code Sample:
 
st:=trimSingles(deleteTrash(st));


Теперь у тебя чистенькая, без глюков строчка. Осталось ее обработать, а это дело плевое.
Code Sample:
 
function summInText(st: string): integer;
var i, _beginN: byte;
   _currentNum: integer; // текущее число
   _result: integer;     // результат
   _singleFlag: boolean; // знак
   _errCode: integer;    //код ошибки
Begin
    _beginN:=1;
    _currentNum:=0;
    _result:=0;
    _singleFlag:=true;
    for i:=1 to length(st) do
     if (st[ i ] in singles )
        then
         begin
          val(copy(st, _beginN, i-_beginN), _currentNum, _errCode);
           if not _singleFlag
             then _currentNum:=_currentNum*(-1);
           _result:=_result+_currentNum;
           // "обнулим" переменные
           _beginN:=i+1;
           if st[ i ]='+'
              then _singleFlag:=true
              else _singleFlag:=false
          end;
    // повторим для последней цифры
    val(copy(st, _beginN, length(st)-_beginN+1), _currentNum, _errCode);
    if not _singleFlag
       then _currentNum:=_currentNum*(-1);
    _result:=_result+_currentNum;
    summInText:=_result
End;



В итоге вся твоя задача свелась к вводу данных и одной строки:
Code Sample:
 
writeLn(summInText(trimSingles(deleteTrash(s))));



Мое решение не претендует на самое быстрое и возможно красивое, но оно более или менее жизненно. Во первых, если бы ты использовал переходы, то конечно уменьшил бы в три раза количество циклов, но сколько было бы у тебя условий??? А каждый лишний шаг в цикле утяжеляет программу. Конечно, можно многое подредактировать, и где-то написать лучше, но моя задача была показать тебе алгоритм и его решение. Плюсом оптимизировать не стал, дабы не потерялась читаемость задачи, где мог, в сложных местах ставил комментарии.

Твое решение сложно тем, что у тебя много-много будет условий. Захочешь свой вариант, давай попробуем разобрать его. Только скажи.

Всего сообщений: 940 | Присоединился: декабрь 2005 | Отправлено: 20 фев. 2008 2:10 | IP
ewgen



Новичок

Cпасибо за подсказку, идея мне понравилась. Я еще подумаю над своим способом ( от нас требуют почему то именно автомат, возможно это связано с тем что в этом семестре у нас курсовой - написать компилятор а там должен быть кусок программы который итерпритирует определённые последовательности символов как команды это как я понимаю может я и не прав ), если возникнут трудности я напишу. И еще, что бы вы посоветовали для повышения моей квалификации ( в программировании я не силен а хотелось бы достичь более высоких результатов ), помимо литературы может еще упражнения какие или разобранные примеры решенных задач.

Всего сообщений: 6 | Присоединился: февраль 2008 | Отправлено: 20 фев. 2008 13:06 | IP
KMA



Долгожитель

Учи С++ и разбирай исходник ядра Линукса. По поводу компиляторов и т. п., всегда можно посмотреть исходники внешняя ссылка удалена. Конечно, базовые знания надо иметь, и такого рода задачи тоже решать. Но это все дело опыта и старания. Начни с мелких задач, потом начинай писать крупные проекты, учись разбивать задачу на отдельные части, писать все процедурно, много много читать и разбирать уйму кодов. Я здесь то сижу ради того, чтобы паскаль не забывать и хоть иногда на нем писать. Всяко что-нибудь пригодиться.  

Всего сообщений: 940 | Присоединился: декабрь 2005 | Отправлено: 20 фев. 2008 19:35 | IP
ewgen



Новичок

Благодарю за совет.

Всего сообщений: 6 | Присоединился: февраль 2008 | Отправлено: 21 фев. 2008 7:55 | IP
Guest



Новичок

Всем привет и с праздником!
У кого-нить есть идеи по решению этой задачи.
Задача:
Имеется n населенных пунктов, пронумерованных от 1 до n. Некоторые пары пунктов соединены дорогами.   Определить, можно ли попасть по этим дорогам из 1-го пункта в n-й. Информация о дорогах задается в виде последовательности пар чисел  i и j  (i<j), указывающих, что i-й и j-й пункты соединены дорогой.

Заранее СПАСИБО!

Всего сообщений: Нет | Присоединился: Never | Отправлено: 23 фев. 2008 14:10 | IP
bekas


Долгожитель

#include "stdafx.h"

#define LEN 20

int   path [ LEN * 2 ];

// Симметричная матрица связности: graph [ i ] [ j ] == 1, если есть путь из i в j
// В данном случае задано 7 вершин, пронумерованных от 0 до 6

chargraph [ LEN ] [ LEN ] =
{
 {0,1,0,0,0,1,1},
 {1,0,1,0,0,0,0},
 {0,1,0,1,1,0,0},
 {0,0,1,0,1,0,0},
 {0,0,1,1,0,1,1},
 {1,0,0,0,1,0,0},
 {1,0,0,0,1,0,0}
};

char visited [ LEN ];
int   index, n = 7;

bool searchR(int v, int w)
{
 int t;

 if(v == w) return true;
 visited [ v ] = 1;
 for(t = 0; t < n; ++t)
 {
    if(graph [ v ] [ t ] == 0 || visited [ t ]) continue;
    if(searchR(t, w))
    {
      if(index == 0)
      {
        path [ index ] = t;
        path [ index + 1 ] = v;
        index += 2;
      }
      else
      {
        path [ index++ ] = v;
      }
      return true;
    }
 }
 return false;
}

void getpath(int n1, int n2)
{
 int i;

 printf("PATH: %d-%d\n", n1, n2);
 if(n1 < 0 || n1 >= n || n2 < 0 || n2 >= n)
 {
   printf("Bad param!\n" ) ;
   return;
 }
 for(i = index = 0; i < n; ++i)
 {
   visited [ i ] = 0;
 }
 if(searchR(n2, n1))
 {
   printf("%d", path [ 0 ] ) ;
   for(n1 = 1; n1 < index; ++n1)
   {
     printf("-%d", path [ n1 ] ) ;
   }
   printf("\n" ) ;
 }
 else
 {
   printf("Path not found!\n" ) ;
 }
}

int main(int argc, char* argv[])
{
 // Делается попытка найти путь из вершины 6 в вершину 2 (не обязательно ближайший)
 getpath(6, 2);

 // Делается попытка найти путь из вершины 2 в вершину 6 (не обязательно совпадающий с 6-2)
 getpath(2, 6);
 return 0;
}

P.S. Не заметил, что эта тема по Паскалю, но думаю разницы особой нет - главное в самом алгоритме...


(Сообщение отредактировал bekas 23 фев. 2008 16:34)

Всего сообщений: 379 | Присоединился: январь 2006 | Отправлено: 23 фев. 2008 16:24 | IP
Guest



Новичок

Да забыл сказать, что ее с помощью рекурсии нужно решить! А здесь я как понял с помощью графа.Но все равно спасибо! Если кто знает как в паскале с помощью рекурсии решить напишите пожалуйста! Спасибо!

Всего сообщений: Нет | Присоединился: Never | Отправлено: 23 фев. 2008 17:36 | IP
Siriusss



Новичок

Задача работает, не получается немного совсем. А может кардинально поменять ее решение - а времени на это нет.
Не получается вывести значения xi, ПРИБЛИЖЕННЫЕ и точные значения функции в точках xi (i=0,1,29/4).
__________________________________________________
program lin_inter;
const h=0.0001;n=29;
type mas=array[0..n]of real;
var x,y,z,L:mas;
    a,b:real;
     i:integer;
begin
{Ввод значений функции с рассчитанным шагом на интервале}
{a=3}
write('a='); readln(a);
{b=3.003}
write('b='); readln(b);
for i:=0 to n do
    begin
    x[ i ]:=a+i*h;
    y[ i ]:=54*sin(x[ i ]/3); - функция моя
    writeln('x[', i ,']=',x[ i ]:10:4,', f(x)=',y[ i ]:10:6,';');
   end;
   writeln;
{Вычисление значения функции в точках z i-тое с помощью линейной интерполяции}
   for i:=0 to n-1 do
   begin
   z[ i ]:=3+i*h+(i mod 4+1)/5*h; - задание точек
   L[ i ]:=y[ i ]+(z[ i ]-x[ i] )*(y[ i+1 ]-y[ i ])/h; - интерполяция - вычисление приближенного решения
   end;
   for i:=0 to n do begin
   if ((i=0)or(i=1)) then writeln('x[', i ,']=',x[ i ]:10:4,',  точное значение функции f(x)=',y[ i ]:10:6,';','  приближенное значение функции f(x)=',L[ i ]:10:6);
    end;
   writeln('x[',29/4:6:4,']=',a+29/4*h:10:4,',  f(x)=',54*sin((a+29/4*h)/3):10:6);
 readln;
end.
__________________________________________________
Не получается вывести приближенное значение функции в точке 29/4 и как следует вывести его же точное значение.
Очень хочется доделать эту задачку...

(Сообщение отредактировал Siriusss 23 фев. 2008 23:29)

Всего сообщений: 28 | Присоединился: апрель 2007 | Отправлено: 23 фев. 2008 19:40 | IP

Эта тема закрыта, новые ответы не принимаются

Переход к теме
<< Назад Вперед >>
Несколько страниц [ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 ]

Форум работает на скрипте © Ikonboard.com