也许大多数人都知道Send + More = Money。好吧,我现在正在学习java,其中一个练习是我必须解决HES + THE = BEST。
现在,到目前为止,我可以/应该使用if-for-while-do循环,没有别的。虽然我确定有不同的方法来解决它,但这不是我正在经历的练习的重点。我必须能够以最有效的方式使用if-for-while-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
}
}
总共需要大约15000个循环周期来解决这个难题。在我看来,这很多。有什么指示吗?
答案 0 :(得分:4)
这里的一个重要问题是:您(您是否想)逻辑推断某些约束并将其应用于您的算法,或者您是否想要强制它?假设前者,其中一些非常明显:
因此你有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;
}
}
答案 1 :(得分:2)
也许您可能想要查看此存储库:它是使用JavaFX解决语言算术问题的解决方案。 Firefly Algorithm for Verbal-arithmetics problem [GitHub]
答案 2 :(得分:1)
不是循环遍历字母的所有值,而是遍历S,E和T的可能值.S + E%10应为T.一旦有了一组潜在的S,E,T解,找到循环通过可能的E + H +(0或1,取决于S + E是否大于9)= S解决方案......依此类推,依此类推。
答案 3 :(得分:1)
我不是专家,但值得研究管理Prolog等限制的语言。这里有一个非常类似的问题:
Prolog是一种不同类型的语言,但如果你这样做是为了你自己的教育,那么它肯定会锻炼你的大脑: - )
可以对字母组合的一般方法进行编码 - 这里不仅仅是相当简单的方法。
替代方案 - 无法保证给出结果 - 是使用遗传算法等优化技术。猜测一些解决方案,并计算它们与正确解决方案的接近程度,然后进行调整。您可以通过此方法获得部分解决方案。
答案 4 :(得分:0)
如果标准方法是brute force,效率会超出窗口,如此处所示。仅使用循环的最有效方式可能涉及计算穷举的各种可能性,存储它们,然后遍历每个可能性以查看它是否有效。
答案 5 :(得分:0)
首先,获取“BEST”的最大值。 假设“HES”具有最高可能值987,则“THE”将为X98,因此“THE”的最高值为698,即987 + 698 = 1685。
如果“THE”具有最高值,则THE为987,HES为876 - > 876 + 987 = 1863,高于1685,因此1863是“最佳”的上限。所以你可以让你的程序将“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循环中的值立即丢弃许多不可能的组合。 我敢打赌,有更多类似的方法来限制可能的解决方案的空间。
这样的程序就不那么复杂了。
答案 6 :(得分:0)
这类问题是查询优化的典型代表。 Java不适用于此。
如果你的国家少于几十亿,那就强行说吧。与创建优化查询引擎相比,运行强力搜索所需的时间少得多 。