【问题标题】:Java Ternary SearchJava 三元搜索
【发布时间】:2015-04-20 20:14:54
【问题描述】:

我正在尝试对字符串数组进行三元搜索。我已经把大部分代码都写下来了,我认为我走在正确的轨道上,但除了-1之外似乎没有得到任何结果。以下是我迄今为止生成的代码。我知道问题出在搜索算法上。我不想使用任何内置的,因为我正在学习。

public static void main(String[] args) {
    //declare a string array with initial size
    String[] songs =  {"Ace", "Space", "Diamond"};
    System.out.println("\nTest binary (String):");
    System.out.println(search(songs,"Ace"));

}  

public static int search(String[] x, String target) {     

   int start=0, end=x.length;

   while (start > end) {
      int midpoint1 = start+(end - start)/3;
      int midpoint2 = start +2*(end-start)/3;
      if ( target.compareTo(x[midpoint1]) == 0 ) 
          return midpoint1;
      else if ( target.compareTo(x[midpoint2]) == 0 ) 
          return midpoint2;   
      else if ( target.compareTo(x[midpoint1]) < 0 ) 
          return end = midpoint1-1;
      else if ( target.compareTo(x[midpoint2]) > 0 ) 
          return start = midpoint2+1;
  }

   return -1;
} 

【问题讨论】:

  • 为什么将方法声明为 int?
  • 你应该学会如何自己调试这些类型的问题。你会一直被这样的事情困住,尤其是在开始的时候。在这种情况下,打印几张就足够了。

标签: java search ternary


【解决方案1】:

你永远不会陷入循环。

int start=0, end=x.length;
while (start > end)

【讨论】:

  • 请您扩展更多。
  • x.length 始终为 0 或更大,因此 start(0) 永远不能大于 end
  • 非常感谢。我不敢相信我看过了
【解决方案2】:

你的while语句是错误的,它应该包含start

【讨论】:

    【解决方案3】:

    试试这个更正的版本,除了 Thomas 和 user2789574 发现的错误之外,你在递归中还有一个错误:

    public static void main(String[] args) {
        //declare a string array with initial size
    
        String[] songs = {"Ace", "Space", "Diamond"};
    
        System.out.println("\nTest binary (String):");
        System.out.println(search(songs, "Ace", 0, 3));
    
    }
    
    public static int search(String[] x, String target, int start, int end) {
    
        if (start < end) {
            int midpoint1 = start + (end - start) / 3;
            int midpoint2 = start + 2 * (end - start) / 3;
            if (target.compareTo(x[midpoint1]) == 0) {
                return midpoint1;
            } else if (target.compareTo(x[midpoint2]) == 0) {
                return midpoint2;
            } else if (x[midpoint1].compareTo(x[midpoint2]) < 0) {
                return search(x, target, midpoint1, end);
            } else {
                return search(x, target, start, midpoint2);
            }
        }
    
        return -1;
    }
    

    【讨论】:

    • 感谢您向我展示我做错了什么。我有一个比我展示的包含 50 个字符串的数组更大的数组,我知道将 "Ace", 0, 3 更改为 Ace, 0, 50 但是当我在数组中运行 seach 另一个字符串时它只是挂断了
    • “三元搜索算法是计算机科学中的一种技术,用于查找递增或递减函数的最小值或最大值”,(来自维基百科),当然这会在“未排序”数据上引发问题。
    • 您最可能想要实现的不是三元搜索,而是Lookup in a ternary Tree ...为此,您必须将 String[] 转换为另一个结构(或至少确保一个不同的结构)结构/顺序...可以将 k-tree 存储为数组)
    • 如果你还是要返回,while 声明也毫无意义。 if 语句有一些开销
    【解决方案4】:

    end = x.length,对于非空字符串,总是返回大于零的数值,并且与 start =0 比较,永远不会进入循环。

    【讨论】:

      【解决方案5】:

      我不确定它现在是否仍然相关,但这里是用 java 中的循环完成的三元搜索(假设数组是预先排序的):

        public static int ternSearch(String[] x, String target) {
              
              if((target.toLowerCase()).compareTo(x[0].toLowerCase()) == 0)
              {
                  return 0;
              }
              if((target.toLowerCase()).compareTo(x[x.length - 1].toLowerCase()) == 0)
              {
                  return x.length-1;
              }
              int mid1 = (int) Math.ceil( x.length/3);
              if((target.toLowerCase()).compareTo(x[mid1].toLowerCase()) == 0)
              {
                  return mid1;
              }
              int mid2 = (int) Math.ceil( x.length*2/3);
              if((target.toLowerCase()).compareTo(x[mid2].toLowerCase()) == 0)
              {
                  return mid2;
              }
              if((target.toLowerCase()).compareTo(x[0].toLowerCase()) > 0&& (target.toLowerCase()).compareTo(x[mid1].toLowerCase()) < 0)
              {
                  for (int i = 1; i < mid1; i++)
                  {
                      if((target.toLowerCase()).compareTo(x[i].toLowerCase()) == 0) 
                      {
                          return i;
                      }
                  }
              }
              else if((target.toLowerCase()).compareTo(x[mid1].toLowerCase()) > 0&& (target.toLowerCase()).compareTo(x[mid2].toLowerCase()) < 0)
              {
                  for (int i = mid1+1; i < mid2; i++)
                  {
                      if((target.toLowerCase()).compareTo(x[i].toLowerCase()) == 0) 
                      {
                          return i;
                      }
                  }
              }
              else if((target.toLowerCase()).compareTo(x[mid2].toLowerCase()) > 0&& (target.toLowerCase()).compareTo(x[x.length-1].toLowerCase()) < 0)
              {
                  for (int i = mid2+1; i < x.length-2; i++)
                  {
                      if((target.toLowerCase()).compareTo(x[i].toLowerCase()) == 0) 
                      {
                          return i;
                      }
                  }
              }
              return -1;
          }
          
          
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多