【问题标题】:Need advice on improving my code: Search Algorithm需要改进我的代码的建议:搜索算法
【发布时间】:2013-04-08 15:53:04
【问题描述】:

我是 C++ 的新手,需要一些建议。 在这里,我编写了一段代码,用于测量任意整数 x 在数组中出现的次数并输出所做的比较。

但是我读到,通过使用多路分支(“分而治之!”)技术,我可以使算法运行得更快。

谁能指出我正确的方向我应该如何去做?

这是我使用的另一种方法的工作代码:

#include <iostream>
#include <cstdlib>
#include <vector>

using namespace std;

vector <int> integers;
int function(int vectorsize, int count);
int x;
double input;

int main()
{
cout<<"Enter 20 integers"<<endl;
cout<<"Type 0.5 to end"<<endl;

while(true)
{
cin>>input;

if (input == 0.5)
break;

integers.push_back(input);
}

cout<<"Enter the integer x"<<endl;
cin>>x;

function((integers.size()-1),0);

system("pause");

}

int function(int vectorsize, int count)
{
    if(vectorsize<0) //termination condition
{
    cout<<"The number of times"<< x <<"appears is "<<count<<endl;
    return 0;
}    

if (integers[vectorsize] > x)
{
    cout<< integers[vectorsize] << " > " << x <<endl;
}

if (integers[vectorsize] < x)
{
    cout<< integers[vectorsize] << " < " << x <<endl;
}
if (integers[vectorsize] == x)
{
    cout<< integers[vectorsize] << " = " << x <<endl;

    count = count+1;
}

return (function(vectorsize-1,count));
}

谢谢!

【问题讨论】:

标签: c++ search divide


【解决方案1】:

如果数组未排序,只需使用单个循环将每个元素与x 进行比较。除非您忘记告诉我们某些事情,否则我认为不需要更复杂的事情。

如果对数组进行排序,则存在具有更好渐近复杂度的算法(例如二进制搜索)。但是,对于一个 20 元素的数组,简单的线性搜索仍然应该是首选策略。

【讨论】:

  • 我明白了。我只是想做一些不同于线性搜索的事情。我会去阅读二进制搜索。谢谢
  • @CandyMan 如果您只是将其作为学习练习,那么我建议您选择一个不同的问题,因为您描述的问题不适合分而治之(没有什么可从中获得)。
  • @CandyMan 您链接到的维基百科文章提供了您可以尝试解决的问题的很好示例(例如排序)。
【解决方案2】:

如果您的数组是有序数组,您可以使用分治策略:

Efficient way to count occurrences of a key in a sorted array

【讨论】:

  • 通常最好将指向另一个问题的链接作为评论而不是答案。
【解决方案3】:

只有当您可以使用它消除一些工作,或者如果您可以在多个计算单元上并行化划分的工作部分时,分而治之算法才有用。在您的情况下,第一个选项对于已经排序的数据集是可能的,其他答案可能已经解决了这个问题。

对于第二种解决方案,算法名称是 map reduce,它将数据集拆分为几个子集,将子集分配给尽可能多的线程或进程,并收集结果以“编译”它们(该术语实际上是“reduce” ) 产生有意义的结果。在您的设置中,这意味着每个线程将扫描自己的数组切片以计数项目,并将其结果返回给“减少”线程,该线程会将它们相加以返回最终结果。 这个解决方案只对大型数据集感兴趣。

有一些关于 SO 上的 mapreduce 和 c++ 的问题,但我会尝试在这里为您提供一个示例实现:

#include <utility>
#include <thread>
#include <boost/barrier>

constexpr int MAP_COUNT = 4;

int mresults[MAP_COUNT];

boost::barrier endmap(MAP_COUNT + 1);

void mfunction(int start, int end, int rank ){
    int count = 0;
    for (int i= start; i < end; i++)
        if ( integers[i] == x) count++;
    mresult[rank] = count;
    endmap.wait();
}

int rfunction(){
    int count = 0;
    for (int i : mresults) {
        count += i;
    }
    return count;
}

int mapreduce(){
    vector<thread &> mthreads;
    int range = integers.size() / MAP_COUNT;
    for (int i = 0; i < MAP_COUNT; i++ )
        mthreads.push_back(thread(bind(mfunction, i * range, (i+1) * range, i)));
    endmap.wait();
    return rfunction();
}

一旦integers 向量被填充,您调用上面定义的mapreduce 函数,它应该返回预期的结果。如您所见,实现非常专业:

  • map 和 reduce 函数专门针对您的问题,
  • 用于映射的线程数是静态的,
  • 我遵循了您的风格并使用了全局变量,
  • 为方便起见,我使用boost::barrier 进行同步

但是,这应该让您对算法有所了解,以及如何将其应用于类似问题。

警告:代码未经测试

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-16
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    相关资源
    最近更新 更多