Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 955

/ вопрос открыт /

Приветствую, уважаемые эксперты!
Подскажите пожалуйста направление, в котором копаться, или может ссылочку на пример, где это используется...
Есть таблица с данными, в которой в зависимости от значения коэффициента "х" принимается значение коэффициента "у". Промежуточные значения определяются интерполяцией. Так вот есть ли какой-то способ внутреннего задания этой таблицы, чтобы при получении от пользователя значения "х" выдавалось значение "у" из таблицы?

Приложение:
  1.  
  2.  
  3.  


pyGama Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: pyGama (статус: Посетитель)
Вопрос отправлен: 4 октября 2007, 18:52
Состояние вопроса: открыт, ответов: 1.

Ответ #1. Отвечает эксперт: min@y™

Вот написал пример на этот вопрос так, насколько я его понял. Там в комментариях пояснение.

 
{  Есть таблица с данными, в которой в зависимости от значения коэффициента "х"
   принимается значение коэффициента "у". Промежуточные значения определяются
   интерполяцией. Так вот есть ли какой-то способ внутреннего задания этой
   таблицы, чтобы при получении от пользователя значения "х" выдавалось значение
   "у" из таблицы?
 
   приблизительный вид таблицы:
   Х   0.8     1,0    2,0    4,0    6,0
   У  30,0    31,5   33,3   34,6   34,8                                        }
 
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils;
 
type
  TVector = array[0..4] of Double;
 
const
  X: TVector = (0.8, 1.0, 2.0, 4.0, 6.0);      // Отсортированы
  Y: TVector = (30.0, 31.5, 33.3, 34.6, 34.8); // по возрастанию
 
var
  TheX, TheY: Double;
  Index: Integer;
  LeftEdge:  Integer = 0;
  RightEdge: Integer = 1;
 
begin
  repeat
    // Ввод аргумента
    Write('Input the X value: ');
    Readln(TheX);
 
    // Проверка диапазона
    if (TheX < X[0]) or (TheX > X[High(X)])
      then WriteLn('Argument is out of bounds.')
      else if TheX = X[High(X)] // Попали на крайнее значение аргумента
             then WriteLn('  Y = ', Y[High(Y)]: 2: 2, #13#10)
             else begin
                    for Index:= 0 to High(X) - 1 do
                      if (TheX >= X[Index]) and (TheX < X[Index + 1])
                        then begin
                               LeftEdge:= Index;          // Индекс левой границы отрезка интерполяции
                               RightEdge:= LeftEdge + 1;  // Индекс правой границы отрезка интерполяции
                               Break;
                             end;
 
                    // Теперь надо вычислить расстояние от левой границы до точки TheX в процентах
                    // относительно длины отрезка интерполяции (>=0 и <1).
                    // Длина отрезка = X[RightEdge] - X[LeftEdge].
                    // Абсолютное расстояние от левой границы до точки "TheX" = TheX - LeftEdge.
                    // Относительное = (TheX - X[LeftEdge]) / (X[RightEdge] - X[LeftEdge]).
 
                    // Относительное расстояние искомой точки TheY от левой границы:
                    // (TheY - Y[LeftEdge]) / (Y[RightEdge] - Y[LeftEdge]). Оно должно быть равно
                    // относительному расстоянию от левой границы до точки TheX.
                    // А теперь, как говорят в школе, составим уравнение:
                    // (TheY - Y[LeftEdge]) / (Y[RightEdge] - Y[LeftEdge]) =
                    // = (TheX - X[LeftEdge]) / (X[RightEdge] - X[LeftEdge]).
                    // Выразим отсюда TheY:
 
                    //         (TheX - X[LeftEdge]) * (X[RightEdge] - X[LeftEdge])
                    // TheY = ----------------------------------------------------- + Y[LeftEdge].
                    //                   X[RightEdge] - X[LeftEdge]
 
                    TheY:= (TheX - X[LeftEdge]) * (Y[RightEdge] - Y[LeftEdge]) /
                           (X[RightEdge] - X[LeftEdge]) + Y[LeftEdge];
 
                    WriteLn('  X[LeftEdge] = ', X[LeftEdge]: 2: 2, '; X[RightEdge] = ', X[RightEdge]: 2: 2);
                    WriteLn('  Length: ', (TheX - X[LeftEdge]): 2: 2,
                            '; Relative length: ', ((TheX - X[LeftEdge]) / (X[RightEdge] - X[LeftEdge])): 2: 2);
                    WriteLn('  Y[LeftEdge] = ', Y[LeftEdge]: 2: 2, '; Y[RightEdge] = ', Y[RightEdge]: 2: 2);
                    WriteLn('  Y = ', TheY: 2: 2, #13#10);
                  end;
  until (TheX < X[0]) or (TheX > X[High(X)]);
 
  Write('Press ENTER for exit...');
  Readln;
end.

Вроде работает, проверь.
Где это используется, увы, не знаю.

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 5 октября 2007, 09:43
Оценка за ответ: 5

Комментарий к оценке: работает, спасибо

Мини-форум вопроса

Всего сообщений: 8; последнее сообщение — 8 октября 2007, 12:03; участников в обсуждении: 4.
Вадим К

Вадим К (статус: Академик), 4 октября 2007, 19:09 [#1]:

вас интересует как прочитать эту таблицу (подозреваю с файла какого то) и хранить в памяти?
Галочка "подтверждения прочтения" - вселенское зло.
Косолапов Дмитрий Юрьевич

Косолапов Дмитрий Юрьевич (статус: 8-ой класс), 4 октября 2007, 21:56 [#2]:

Обычно двухмерные массивы используют, потом есть TStringGrid... Надеюсь, формулу интерполяции знаете?
pyGama

pyGama (статус: Посетитель), 5 октября 2007, 09:15 [#3]:

Формулу интерполяции знаем. Нет, Вадим, таблица должна уже быть каким-то образом задана в программе, наверно действительно массивом, хотя как конкретно его задать не совсем понятно. Если б "х" шел с одинаковым шагом: 1,2,3,4..., тогда б очевиднее было.
min@y™

min@y™ (статус: Доктор наук), 5 октября 2007, 09:45 [#4]:

Пардон, в комментарии ошибочка (а в коде правильно):
//         (TheX - X[LeftEdge]) * (Y[RightEdge] - Y[LeftEdge])
// TheY = ----------------------------------------------------- + Y[LeftEdge].
//                   X[RightEdge] - X[LeftEdge]
Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп!
Вадим К

Вадим К (статус: Академик), 5 октября 2007, 11:18 [#5]:

pyGama
ну так в чём проблема? разве не можно завести массив записей? Ну где то так
Type 
  TPointR = record
  X,Y:Double;
  end;
 table:array[0..99] of TPointR;
Теперь допустимы конструкции вида
mas[1].X, mas[5].Y
Вот только эффективность поиска Y по X может быть маленькой, если массив большой. Хотя никто не мешает написать бинарный поиск.
Галочка "подтверждения прочтения" - вселенское зло.
Косолапов Дмитрий Юрьевич

Косолапов Дмитрий Юрьевич (статус: 8-ой класс), 5 октября 2007, 18:35 [#6]:

Может просто двухмерный массив? Первая строка - иксы, вторая - игреки. Хотя мало чем отличается от двух массивов.
pyGama

pyGama (статус: Посетитель), 8 октября 2007, 12:01 [#7]:

Спасибо, работает.Но если усложнить, то наверно этот способ не подойдет.
если есть таблица такого вида:
Y
Х 0.5 0.6 0.8 1.0

1 11,5 12,4 14,8 18,0
2 12,0 13,0 16,1 20,4
4 12,3 13,3 16,6 21,6
6 12,4 13,5 16,8 22,1

чтобы получить Z, нужно интерполировать и по Х, и по Y.
Тут наверно действительно надо, как советует Вадим К, создать массив записей, но как удобней всего будет присвоить ему все значения в разделе объявления а не в самой программе(может не совсем корректно сформулировал - чайник:D)
pyGama

pyGama (статус: Посетитель), 8 октября 2007, 12:03 [#8]:

Упс, там Y должен стоять посередине над 0.5, 0.6... то есть Y принимает значения 0.5, 0.6, 0.8, 1.0. А Х - 1, 2, 4, 6.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:44
Выполнено за 0.03 сек.