递归二进制搜索字符串-C ++

时间:2018-07-29 21:04:07

标签: c++ recursion binary-search

我正在尝试实现功能// once at he beginning of your program (before any use of default SSLContext) // or instead can be done on the command line with -Dprop=value System.setProperty ("javax.net.ssl.keyStore", filepath); System.setProperty ("javax.net.ssl.keyStorePassword", password); System.setProperty ("javax.net.ssl.keyStoreType", "PKCS12" or "JKS"); -- if not default System.setProperty ("javax.net.ssl.trustStore", filepath); System.setProperty ("javax.net.ssl.trustStorePassword", password); System.setProperty ("javax.net.ssl.trustStoreType", "PKCS12" or "JKS"); -- if not default // when (each time) you want to make a request: URL url = new URL ("https://hello-signs.api-dev.myname.com/v2/oauth2/client_credential/accesstoken?grant_type=client_credentials"); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); // we aren't actually using S-specific items, so could instead use // HttpURLConnection especially if you want to mix HTTPS and HTTP; // or you could use the Https version to tweak some SSL/TLS parameters conn.setRequestMethod ("POST"); conn.setRequestHeader ("Content-Type","application/x-www-form-urlencoded"); conn.setDoOutput (true); OutputStream os = conn.getOutputStream(); os.write ("client_id=xxccvvbbnniioopp&client_secret=zoopopopopopppp".getBytes()); os.close(); os.connect(); // optional, can help localize exceptions // depending on what you want to do with the result(s): ... conn.getResponseCode() and/or conn.getResponseMessage() ... ... conn.getHeaderField{,Int,Long,s}("id") ... ... conn.getContent{Type,Length[Long],Encoding,}() ... ... conn.getInputStream() then read from it, including decoding various formats or charsets as needed/desired ... conn.disconnect(); // when done ,该功能试图查看单词是否与预排序词典中的任何单词匹配。下面是我当前的实现方式:

findMatchesInDict

void findMatchesInDict(string word, int start, const string dict[], int end, string results[], int& totalResults) { // initial start = 0 index // initial end = last index of dict array int middle = start + (end - start) / 2; if (end < start) return; if (word == dict[middle]) // if we found a match storeUniqueMatches(word, 0, results, totalResults); else if (word < dict[middle]) findMatchesInDict(word, start, dict, middle - 1, results, totalResults); else findMatchesInDict(word, middle + 1, dict, end, results, totalResults); } 函数正常工作(这只是将匹配的单词存储在storeUniqueMatches数组中,确保没有重复的单词被存储。

该功能将只匹配词典中的选定单词,而不匹配其他单词。

关于为什么可能无法正常工作的任何想法?


作为参考,此实现有效,但效率极低,并且会导致堆栈溢出错误。

results

1 个答案:

答案 0 :(得分:0)

我仍然相信OP犯错了1次。

我强烈怀疑

findMatchesInDict(word, start, dict, middle - 1, results, totalResults);

应该是

findMatchesInDict(word, start, dict, middle, results, totalResults);

我做了自己的小样本。 (因此,我对OP的运行方式感到不走运,因此对代码进行了一些重新设计。)

#include <iostream>
#include <string>

size_t find(const std::string &word, const std::string dict[], size_t i0, size_t size)
{
  if (!size) return (size_t)-1; // bail out with invalid index
  const size_t i = i0 + size / 2;
  return word == dict[i]
    ? i
    : word < dict[i]
      ? find(word, dict, i0, i - i0)
      : find(word, dict, i + 1, i0 + size - (i + 1));
}

int main()
{
  const std::string dict[] = {
    "Ada", "BASIC", "C", "C++",
    "D", "Haskell", "INTERCAL", "Modula2",
    "Oberon", "Pascal", "Scala", "Scratch",
    "Vala"
  };
  const size_t sizeDict = sizeof dict / sizeof *dict;
  unsigned nErrors = 0;
  // brute force tests to find something what is in
  for (size_t n = 1; n <= sizeDict; ++n) {
    for (size_t i = 0; i < n; ++i) {
      if (find(dict[i], dict, 0, n) >= n) {
        std::cerr << "ALERT! Unable to find entry " << i << " in " << n << " entries!\n";
        ++nErrors;
      }
    }
  }
  // brute force tests to find something what is not in
  for (size_t n = 1; n <= sizeDict; ++n) {
    if (find("", dict, 0, n) < n) {
      std::cerr << "ALERT! Able to find entry '' in " << n << " entries!\n";
      ++nErrors;
    }
    for (size_t i = 0; i < n; ++i) {
      if (find(dict[i] + " + Assembler", dict, 0, n) < n) {
        std::cerr << "ALERT! Able to find entry '" << dict[i] << " + Assembler' in " << n << " entries!\n";
        ++nErrors;
      }
    }
  }
  // report
  if (!nErrors) std::cout << "All tests passed OK.\n";
  else std::cerr << nErrors << " tests failed!\n";
  // done
  return nErrors > 0;
}

Live Demo on coliru

此代码大部分是蛮力测试代码:

  1. 从1到dict大小的每个长度都经过测试。对于每个长度,将搜索dict的任何条目。

  2. 从1到dict大小的每个长度都经过测试。对于每个长度,都会测试空字符串(在任何其他条目之前)以及任何经过修改的条目。 (修改后,该修改将介于未修改的条目与其后继条目之间,或者位于最后一个条目之后。)

输出:

All tests passed OK.

一切顺利。

然后我替换了

find(word, dict, i0, i - i0)

使用

find(word, dict, i0, i - i0 > 0 ? i - i0 - 1 : 0)

类似于OP的代码在我看来是什么错误。

输出:

ALERT! Unable to find entry 0 in 2 entries!
ALERT! Unable to find entry 0 in 3 entries!
ALERT! Unable to find entry 1 in 4 entries!
ALERT! Unable to find entry 1 in 5 entries!
ALERT! Unable to find entry 3 in 5 entries!
ALERT! Unable to find entry 0 in 6 entries!
ALERT! Unable to find entry 2 in 6 entries!
ALERT! Unable to find entry 4 in 6 entries!
ALERT! Unable to find entry 0 in 7 entries!
ALERT! Unable to find entry 2 in 7 entries!
ALERT! Unable to find entry 4 in 7 entries!
ALERT! Unable to find entry 0 in 8 entries!
ALERT! Unable to find entry 3 in 8 entries!
ALERT! Unable to find entry 5 in 8 entries!
ALERT! Unable to find entry 0 in 9 entries!
ALERT! Unable to find entry 3 in 9 entries!
ALERT! Unable to find entry 6 in 9 entries!
ALERT! Unable to find entry 1 in 10 entries!
ALERT! Unable to find entry 4 in 10 entries!
ALERT! Unable to find entry 7 in 10 entries!
ALERT! Unable to find entry 1 in 11 entries!
ALERT! Unable to find entry 4 in 11 entries!
ALERT! Unable to find entry 7 in 11 entries!
ALERT! Unable to find entry 9 in 11 entries!
ALERT! Unable to find entry 1 in 12 entries!
ALERT! Unable to find entry 3 in 12 entries!
ALERT! Unable to find entry 5 in 12 entries!
ALERT! Unable to find entry 8 in 12 entries!
ALERT! Unable to find entry 10 in 12 entries!
ALERT! Unable to find entry 1 in 13 entries!
ALERT! Unable to find entry 3 in 13 entries!
ALERT! Unable to find entry 5 in 13 entries!
ALERT! Unable to find entry 7 in 13 entries!
ALERT! Unable to find entry 9 in 13 entries!
ALERT! Unable to find entry 11 in 13 entries!
35 tests failed!

好吧。实际上,这并没有证明与OP的代码有关。

但是,这显示了

  1. “减1”可以从本质上破坏二进制搜索。

  2. 如何设计暴力测试以发现此类错误。

因此,这有望帮助OP自己发现算法中的错误(实际上对他来说更有价值)。