| 
| 
 | Вопрос # 955/ вопрос открыт / | 
 |  Приветствую, уважаемые эксперты!Подскажите пожалуйста направление, в котором копаться, или может ссылочку на пример, где это используется...
 Есть таблица с данными, в которой в зависимости от значения коэффициента "х" принимается значение коэффициента "у". Промежуточные значения определяются интерполяцией. Так вот есть ли какой-то способ внутреннего задания этой таблицы, чтобы при получении от пользователя значения "х" выдавалось значение "у" из таблицы?
 
|  |   Вопрос задал: 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 (статус: Посетитель), 5 октября 2007, 09:15 [#3]:Формулу интерполяции знаем. Нет, Вадим, таблица должна уже быть каким-то образом задана в программе, наверно действительно массивом, хотя как конкретно его задать не совсем понятно. Если б "х" шел с одинаковым шагом: 1,2,3,4..., тогда б очевиднее было. |  
|   | 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 (статус: Посетитель), 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.
 Тут наверно действительно надо, как советует Вадим К, создать массив записей, но как удобней всего будет присвоить ему все значения в разделе объявления а не в самой программе(может не совсем корректно сформулировал - чайник
  ) |  
|   | pyGama (статус: Посетитель), 8 октября 2007, 12:03 [#8]:Упс, там Y должен стоять посередине над 0.5, 0.6... то есть Y принимает значения 0.5, 0.6, 0.8, 1.0. А Х - 1, 2, 4, 6. |  Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |