Java 更有效的口头算术/字母计算方法?

Java 更有效的口头算术/字母计算方法?,java,performance,math,cryptarithmetic-puzzle,alphametic-question,Java,Performance,Math,Cryptarithmetic Puzzle,Alphametic Question,也许你们中的大多数人都知道发送+更多=金钱。嗯,我目前正在学习java,其中一个练习是我必须解决HES+the=BEST 现在,到目前为止,我可以/应该使用if-for-while-do循环,而不是其他。虽然我确信有不同的方法可以解决这个问题,但这不是我正在进行的练习的重点。我必须能够以最有效的方式使用if-for-do循环 我的问题?我似乎想不出一个有效的方法来解决它!我想出了这个办法,解决了这个难题,但也许是最有效的方法: public class Verbalarithmetics {

也许你们中的大多数人都知道发送+更多=金钱。嗯,我目前正在学习java,其中一个练习是我必须解决HES+the=BEST

现在,到目前为止,我可以/应该使用if-for-while-do循环,而不是其他。虽然我确信有不同的方法可以解决这个问题,但这不是我正在进行的练习的重点。我必须能够以最有效的方式使用if-for-do循环

我的问题?我似乎想不出一个有效的方法来解决它!我想出了这个办法,解决了这个难题,但也许是最有效的方法:

public class Verbalarithmetics {

    public static void main (String args[]) {
        // Countint Variables
        int index_h = 0;
        int index_e = 0;
        int index_s = 0;
        int index_t = 0;
        int index_b = 0;

        // Start with h = 1 and increase until the else-if statement is true
        for(int h = 1; h <= 9; h++) { // h = 1, because first Symbol can't be zero
            index_h++;
                // Increase e so long until e equals h
                for(int e = 0; e <= 9; e++) {
                    index_e++;
                 if (e == h) {
                    continue;
                 }

                 // Increase s so long until s equals h or e
                 for(int s = 0; s <= 9; s++) {
                     index_s++;
                    if (s == h || s == e) {
                       continue;
                    }//end if

                    // Increase t so long until t equals h or e or s.
                    for(int t = 1; t <= 9; t++) { // t = 1, because 1st Symbol cant be zero
                        index_t++;
                      if(t == h || t == e || t == s) {
                         continue;
                      }// end if

                      // Increase b so long until b equals h, e, s or t.
                      for(int b = 1; b <= 9; b++) { // b = 1, weil das 1. Symbol nicht für eine 0 stehen darf
                          index_b++;
                          if (b == h || b == e || b == s || b == t) {
                              continue;
                          }// end if

                          // x = 100*h + 10*e + s
                          // y = 100*t + 10*h + e
                          // z = 1000*b + 100*e + 10*s + t
                          // Check if x+y=z, if true -> Print out Solution, else continue with the upper most loop
                          else 
                              if (100*h + 10*e + s + 100*t + 10*h + e == 1000*b + 100*e +10*s + t) {
                                  System.out.println("HES + THE = BEST => " + h + e + s + " + " + t + h + e + " = " + b + e + s + t);
                                  System.out.println("With H=" + h + ", E=" + e + ", S=" + s + ", T=" + t + ", und B=" + b + ".");
                                  System.out.println("It took " + index_h + 
                                          " Loop-Cycles to find 'h' !");
                                  System.out.println("It took " + index_e + 
                                          " Loop-Cycles to find 'e' !");
                                  System.out.println("It took " + index_s + 
                                          " Loop-Cycles to find 's' !");
                                  System.out.println("It took " + index_t + 
                                          " Loop-Cycles to find 't' !");
                                  System.out.println("It took " + index_b + 
                                          " Loop-Cycles to find 'b' !");
                                  System.out.println("This is a total of " + (index_h + index_e + index_s + index_t + index_b) + 
                                          " Loop-Cycles");
                          }// end else if
                      }//end for
                    }//end for
                 }//end for
              }//end for
        }//end for
    }   
}
公共类算术{
公共静态void main(字符串参数[]){
//计数变量
int索引_h=0;
int索引_e=0;
int索引_s=0;
int索引_t=0;
int索引_b=0;
//从h=1开始,然后增加,直到else if语句为真

对于(inth=1;h如果采用标准方法,效率就会消失,正如本文所建议的。只使用循环的最有效方法可能包括计算一组详尽的可能性,存储它们,然后遍历每一个可能性,看看是否有效。

循环thr,而不是遍历字母的所有值通过S、E和T的可能值。S+E%10应该是T。一旦你有了一组潜在的S、E、T解,通过可能的E+H+(0或1,取决于S+E是否大于9)=S解……等等找到循环。这里的大问题是:你能(你想)吗从逻辑上推导出某些约束并将其应用于算法,还是要强制执行?假设是前者,其中一些约束非常明显:

  • B=1
  • T不能为0(因为它是中的第一个),因此s和E也不能为0
  • T=E+S%10
因此,你有S,E,H循环,给你最多9*8*8个组合,也就是576。再加上H+T必须大于或等于9,你会进一步减少

更新这里有一个快速而丑陋的解决方案。它仅基于上面列出的3个约束条件

public class Puzzle {
  public static void main(String[] args) {
    for (int S = 1; S<10; S++) {
      for (int E = 1; E<10; E++) {
        if (S==E) continue; // all letters stand for different digits
        for (int H = 1; H<10; H++) {
          if (H==E || H==S) continue; // all letters stand for different digits
          checkAndPrint(S, E, H);
        }
      } // for
    } // for
  } // main

  private static boolean checkAndPrint(int S, int E, int H) {
    int T = (S + E) % 10;
    int S1 = (E + H) + (S + E) / 10; // calculates value for 'S' in 'BEST' (possibly + 10)
    if (S1 % 10 != S) return false;
    int E1 = H + T + S1 / 10; // calculates value for 'E' in 'BEST' (possibly + 10)
    if (E1 % 10 != E) return false;
    System.out.println(H + "" + E + "" + S + " + " + T + "" + H + "" + E + " = 1" + E + "" + S + "" + T);
    return true;
  }
}
公共类难题{
公共静态void main(字符串[]args){

对于(int S=1;Suhm),您可以在您的方法中以优化的形式做很多事情

首先,获取“最佳”的最大值。 假设“HES”有可能的最高值987,那么“the”将是X98,因此“the”的最高值为698,即987+698=1685

如果“THE”的值最高,则为987,HES为876->876+987=1863,高于1685,因此1863是“best”的上限。因此,您可以让您的程序将“B”的上限调整为1(在本例中,已产生第一位数字)。 BEST的下限很容易,因为它是1023

然后你可以这样做:

for(i=102;i<=987;i++)
{
    for(j=1023-i;j<=(1863-i < 987 ? 1863-i:987);j++)
    {
        //check if the solution matches and doesn't have duplicate digits
    }
}

for(i=102;i这类问题是查询优化的典型代表。Java不适合这类问题


如果你只有不到数百亿个州,就对其进行暴力搜索。与创建优化查询引擎相比,运行暴力搜索所需的时间要少得多。

我不是专家,但值得一看管理约束的语言,如Prolog。这里有一个非常类似的问题:

Prolog是一种不同类型的语言,但如果你这样做是为了自己的教育,那么它肯定会锻炼你的大脑:-)

这将是可能的代码通用方法的字母-不仅仅是一个相当简单的一个在这里


另一种方法(不能保证给出结果)是使用优化技术,如遗传算法。猜测一些解决方案,计算它们与正确解决方案的接近程度,然后进行调整。通过这种方法,您可以得到部分解决方案。

也许您需要查看此存储库:这是一个解决方案使用JavaFX解决口头算术问题。

Hm,我想可能有一些不同的、更有效的方法,用控制流语句来解决这个HES+THE=最佳口头算术。因为在我看来,解决方案的15000个循环和奇数个循环是很多的。也许我只是错了,我不知道。效率来得晚,我只是想知道如果可能还有另一种方法……啊,现在我明白了布莱恩·施罗斯写的东西。我一直在试图找出他的答案。
事实上,我得出的结论至少是B=1,T=1和H=1(意思不可能是0),因为这些人中的每一个都是每个“单词”的第一位.嗯,T=E+S%10,我没有得出结论,但很有意思。
我要试试这个。感谢各位的指点!如果你能逻辑推理,最简单的解决方案是在一次迭代中-将每件事设置为正确的值,因为整个解决方案都可以逻辑推理,今天到此为止!我想如果你要这么做的话从逻辑上讲,你需要用算法来完成所有的逻辑运算。因此,推断B=1是可以的,但你应该包括计算它为1的代码行,而不是仅仅将它定义为1。当然,这是一个自我挑战,所以你可以做任何你想做的事情!布莱恩-像这样的难题不一定只有一个解决方案。这一个,特别是,h如6所示,虽然您可以手动查找它们,但它确实涉及到实际的迭代和检查,而且您的CPU可能会更快:)您的解决方案为外循环提供了885次迭代,为内循环提供了66到1827次迭代;这绝对不是最理想的方法。此外,虽然您描述的逻辑确实简单明了,但两个“for”循环都不是;“check”基于这种方法的函数可能也不是很简单。哦,我知道这绝不是最终的解决方案,如果我要解决这个问题,我会寻找其他方法来约束迭代。此外,我会使用我的c语言的Min()函数