14

質問は簡単です。関数があるとしましょう

double interpolate (double x);


そして、たとえば
5 15
7 18
10 22などの既知の x-> y のマップを持つテーブルがあることに
注意してください:実際のテーブルはより大きく、これは単なる例です。

したがって、8 の場合、18+((8-7)/(10-7))*(22-18)=19.3333333 が返されます。

私が見つけたクールな方法の 1 つは、 http://www.bnikolic.co.uk/blog/cpp-map-interp.htmlです (簡単に言えば、std::map、key= x、value = y for x->y を使用します)。データペア)。

誰かが if else if else way とは何かと尋ねると、基本的には次のようになります。

if ((x>=5) && (x<=7))
{
//interpolate
}
else 
     if((x>=7) && x<=10)
     {
      //interpolate
     }

では、それを行うためのより賢い方法や、最先端の地図を作成する方法はありますか? :)

ところで、私は C++ のソリューションを好みますが、明らかに、C++ に 1:1 でマッピングされる言語ソリューションはどれも優れています。

4

6 に答える 6

4

二分探索木を使用して内挿データを格納できます。これは、補間を O(log N) 時間で実行できるため、N 補間点の大きなセットがある場合に役立ちます。ただし、あなたの例では、そうではないようで、RedX によって提案された線形検索の方が適切です。

#include <stdio.h>
#include <assert.h>

#include <map>

static double interpolate (double x, const std::map<double, double> &table)
{
    assert(table.size() > 0);

    std::map<double, double>::const_iterator it = table.lower_bound(x);

    if (it == table.end()) {
        return table.rbegin()->second;
    } else {
        if (it == table.begin()) {
            return it->second;
        } else {
            double x2 = it->first;
            double y2 = it->second;
            --it;
            double x1 = it->first;
            double y1 = it->second;
            double p = (x - x1) / (x2 - x1);
            return (1 - p) * y1 + p * y2;
        }
    }
}

int main ()
{
    std::map<double, double> table;
    table.insert(std::pair<double, double>(5, 6));
    table.insert(std::pair<double, double>(8, 4));
    table.insert(std::pair<double, double>(9, 5));

    double y = interpolate(5.1, table);

    printf("%f\n", y);
}
于 2012-07-10T10:36:24.977 に答える
3

はい、それらの間隔と自然数の間のマップで考える必要があると思います。つまり、間隔にラベルを付けてスイッチを使用するだけです。

switch(I) {

    case Int1: //whatever
        break;

      ...

    default:

}

わかりません、それは私が最初に考えたものです。

数値が比較的小さい間隔内にある場合、 EDIT Switch は if-else よりも効率的です (これは、マッピングを行うときに考慮する必要があります)。

于 2012-07-09T14:25:35.500 に答える
1

あなたがすでにそれを手に入れた方法はかなり読みやすく理解しやすいものであり、「賢い」解決策については多くのことが言えます。&&ただし、シーケンスが順序付けられているため、下限チェックと不器用さをなくすことができます。

if (x < 5)
  return 0;
else if (x <= 7)
  // interpolate
else if (x <= 10)
  // interpolate
...
于 2012-07-10T09:57:00.207 に答える