【问题标题】:Looking for Search algorithm in both direction - c / c++ / awk寻找双向搜索算法 - c / c++ / awk
【发布时间】:2014-02-16 08:07:25
【问题描述】:

我正在做一些计算建模,其中我需要搜索不规则间隔且数据未排序的数据,所以这里是场景

我的样本数据点

col1 col2 
1    92
9    45
7    22
2    14
5    10

所以我正在寻找的搜索算法是这样的,

说如果key = 2 那么函数应该返回2 的索引,因为它可用,例如我想搜索3,它不在col1 中,因为它不可用,我需要搜索最近的两个方向的值,即25 的索引

如果是awk,可以使用类似这样的方式搜索确切的键

  function search(Arr,key){
                             if((key in Arr))
                              return key
                          }

但我真的不知道只能在上下方向搜索最近的值,以防找不到确切的键

我希望我的要求是明确的,如果投反对票,也请发表您的评论,因为我的问题是因为声誉较低(这个论坛的新手),我无法为有用的答案投票,请共同操作。

【问题讨论】:

  • 您是否尝试对数组进行排序,然后使用Binary Search,因为这可以为您提供上限和下限。
  • 在 shell 或 AWK 中执行它会很困难,除非您像在 C 或 C++ 程序中那样读取文件。在 C 中这并不难,而在 C++ 中则很容易。但是,没有人可能会给您一个完整的解决方案(根据所使用的语言,可能会非常有所不同),而无需您付出一些努力来展示您迄今为止所尝试的内容。
  • @Joachim Pileborg :感谢您的回复,我实际上正在使用 matlab,因为它有很多内置功能,但 matlab 非常慢.. 所以我在 c / c++ / awk 寻找解决方案
  • @G one : 感谢您的回复,请给我一个示例。我不是很好的程序员..
  • 只是谷歌搜索(二进制搜索)和排序技术(合并、冒泡、快速),你会发现很多例子。还是你不明白然后回复:)

标签: c++ c shell awk


【解决方案1】:

壳牌解决方案,

perl -lane'
BEGIN{ $k=pop }
push @r, [@F];
END { 
  for (sort{ $a->[0] <=> $b->[0] } @r) {
    $v= $_->[0] <=> $k;
    $h{$v} = $_->[1];
    last if $v >0;    
  }
  print join " ", ($h{0} or @h{-1,1});
}
' file 3

输出

14 10

【讨论】:

    【解决方案2】:

    因为你没有排序,所以最好同时搜索exact、lower和upper,只遍历一次数据。

    #include <iostream>
    #include <vector>
    #include <utility>
    
    using Samples = std::vector<std::pair<int,int>>;
    
    Samples::const_iterator Find( Samples const & samp_, int val_, Samples::const_iterator & prev_, Samples::const_iterator & next_ ) {
        auto end = std::end(samp_);
        auto lower = end;
        auto upper = end;
        auto it = begin(samp_);
        for( ; it!=end; ++it) {
            if ( it->first == val_ )
                return it;
            if ( it->first < val_ && ( lower == end || lower->first < it->first ) )
                lower = it;
            else if ( it->first > val_ && ( upper == end || upper->first > it->first ) )
                upper = it;
        }
        prev_ = lower;
        next_ = upper;
        return end;
    }
    
    std::ostream & operator<<( std::ostream & os, std::pair<int,int> const & p ) {
        return os << "( " << p.first << ", " << p.second << " )";
    }
    
    int main() {
        Samples samps { {1,92}, {9,45},{7,22},{2,14},{5,10} };
    
        auto test = [&] ( int v ) {
            Samples::const_iterator lower;
            Samples::const_iterator upper;
            auto result = Find( samps, v, lower, upper );
            if ( result != end( samps ) ) {
                std::cout << "found " << *result << std::endl;
            } else {
                std::cout << "not found ";
                if ( lower  != end( samps ) )
                    std::cout << "lower is " << *lower;
                else 
                    std::cout << "no lower";
                if ( upper  != end( samps ) )
                    std::cout << " upper is " << *upper;
                else 
                    std::cout << " no upper";
                std::cout << std::endl; 
            }
        };
        test(2);
        test(3);
        test(12);
        test(-1);
    }
    

    结果:

    found ( 2, 14 ) 
    not found lower is ( 2, 14 ) upper is ( 5, 10 ) 
    not found lower is ( 9, 45 ) no upper
    not found no lower upper is ( 1, 92 )
    

    【讨论】:

    • 你真是一流的程序员,我真的不知道我需要多少周/几个月才能将你的c++代码转换为c。你能在你的代码中添加评论吗?这样我就可以轻松地将其转换为 c
    • 只需将迭代器和自动替换为 int 索引,begin 为 0,end 为 -1,pair 的向量是具有 tko 成员 pair samps[N]; 的结构对的 C 数组,然后您进行迭代索引从 0 到 size 的数组。
    • 你是怎么编译的?我收到错误消息我在终端上尝试了g++ search.cpp
    • 需要'-std=c++11'选项
    • $ g++ -std=c++11 search.cpp cc1plus: 错误:无法识别的命令行选项'-std=c++11'
    【解决方案3】:

    在 Gnu Awk 版本 4 中,您可以使用 PROCINFO["sorted_in"],例如:

    gawk -vkey=7 -f a.awk file
    

    a.awk 在哪里:

    {
        a[$1]=$2
    }
    END {
        if (key in a)
            print "Found key "key" with value "a[key]
        else {
            PROCINFO["sorted_in"]="@ind_num_asc"
            for (i in a) {
                if (i+0>key) { k=i; break}
                j=i
            }
            if (j)  
                print "Prev key: "j
            if(k)
                print "Next key: "k
        }
    }
    

    输出:

    $gawk -vkey=6 -f a.awk file
    
    Prev key: 5
    Next key: 7
    
    $gawk -vkey=5 -f a.awk file
    
    Found key 5 with value 10
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 2017-07-02
      • 1970-01-01
      • 1970-01-01
      • 2011-10-18
      • 1970-01-01
      相关资源
      最近更新 更多