|
Вопрос # 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.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|