使用递归将数字转换为其他数字

问题描述

| 我正在尝试为以下任务创建算法: 我有两个整数a≤b 该算法必须通过加1和乘以2运算将a转换为b。例如,如果a = 5且b = 23,则程序应输出类似23 =((5 * 2 +1)* 2 +1)的内容。 我必须使用递归 我已经搜索过很多次了,但是我所能找到的是关于如何转换矩阵,如何进行几何转换,如何将字符串转换为另一字符串以及类似内容的想法。 有人有什么想法吗?     

解决方法

        这是查找操作次数最少的转换的方法: (编辑:添加了括号)
public static void main (String [] args)
{
    int a = 5,b = 23;
    System.out.println (transform (a,b) + \" = \" + b);
}

public static String transform (int a,int b)
{
    if (a == b) return \"\" + a;
    if (b % 2 == 0 && 2 * a <= b)
    {
        b = b / 2;
        return transform (a,b) + \" * 2\";
    }
    else
    {
        b = b - 1;
        return \"(\" + transform (a,b) + \" + 1)\";
    }
}
    ,        这实际上可以打印出来,但是我不确定,它可能与您要查找的不完全相同。
private static String doDo(int a,int b,StringBuilder sb) {
    if (a == b) {
      String ret = sb.toString();
      int charCount = ret.replaceAll(\"[^)]\",\"\").length();
      for (int i = 0; i < charCount; i++)
        ret = \"(\" + ret;
      return ret;
    }
    if (a < (b/2f)) {
      sb.append(\")*2+1\");
      return doDo(a*2 + 1,b,sb);
    } else {
      sb.append(\"+1\");
      return doDo(a+1,sb);
    }
  }

System.out.println(doDo(5,23,new StringBuilder().append(\"5\")));
打印->
((5)*2+1)*2+1
    ,        我认为以下方法应该为您工作:
int transform(int a,int b) {
   if (a>= b)
      return a;
   else if (a*2 <= b)
      return transform(2*a,b);
   else
      return transform(a + 1,b);
}
    ,        这是您可以使用的一些伪代码
transform(a,b)
start
   if a >= b
       return
   else
     print formatted progress 
     transform(a * 2 + 1,b)
end
    ,        如果您不想过度拍摄,请使用此选项(@anubhava解决方案的修改版本)。
int transform(int a,int b) {
   if (a >= b){
      return a;
   } else {
      int c = a*2 + 1;
      if (c>b){
          return a;
      } else {
          return transform(c,b);
      }
  }
}
    ,        这是使用递归来确定以最少数量的操作进行转换的最佳策略的版本。我假设每次加倍,就算是一次操作。每次添加1,就算是一次操作,目标是最大程度地减少操作总数。 并在5至23个示例中进行测试,得出:
((((5)*2)+1)*2)+1=23
您可能会对语法感到厌烦,但是希望稍微冗长一些有助于显示代码的意图。 在我使用他的想法进行字符串格式化的想法时,向josh.trow致以技巧。
import java.util.ArrayList;
import java.util.List;

public class DoubleAndAddAlgorithm {
    public enum Op {
        DOUBLE,ADD_ONE
    }

    private static List<Op> getOptimalTransform(int a,int b) throws IllegalArgumentException {
        // Returns the list of operations that comprises the optimal way to get from a to b

        // If a is already bigger than b,we have a problem
        if (a > b) {
            throw new IllegalArgumentException(\"a cannot be greater than b\");
        }

        List<Op> result = new ArrayList<Op>();

        // If we can get there in one operation,do so
        if (2*a == b) {
            result.add(Op.DOUBLE);
        } else if (a+1 == b) {
            result.add(Op.ADD_ONE);
        }

        // If doubling would cause us to overshoot,all we can do is add 1
        // and take it from there...
        else if (2*a > b) {
            result.add(Op.ADD_ONE);
            result.addAll(getOptimalTransform(a+1,b));
        }

        // Otherwise,let\'s try doubling,and let\'s try adding one,and use
        // recursion to see which gets us to the target quicker
        else {
            List<Op> trialResultDouble = getOptimalTransform(2*a,b);
            List<Op> trialResultAddOne = getOptimalTransform(a+1,b);

            // Let\'s say (arbitrarily),that if neither operation results in us
            // getting to the target any quicker than the other,we choose to add 1
            if (trialResultDouble.size() < trialResultAddOne.size()) {
                result.add(Op.DOUBLE);
                result.addAll(trialResultDouble);
            } else {
                result.add(Op.ADD_ONE);
                result.addAll(trialResultAddOne);
            }
        }
        return result;
    }

    public static String getFormattedResult(int a,int b) {
        try {
            List<Op> ops = getOptimalTransform(a,b);

            StringBuilder sb = new StringBuilder();
            sb.append(Integer.toString(a));

            for (Op op: ops) {
                if (op == Op.DOUBLE) {
                    sb.insert(0,\"(\");
                    sb.append(\")*2\");
                } else if (op == Op.ADD_ONE) {
                    sb.insert(0,\"(\");
                    sb.append(\")+1\");
                }
            }

            sb.append(\"=\");
            sb.append(Integer.toString(b));

            return sb.toString();
        } catch (IllegalArgumentException e) {
            return \"Illegal arguments supplied\";
        }
    }

    public static void main(String[] args) {
        System.out.println( getFormattedResult(5,23) );
    }
}
    ,        搜索一种称为double&add的算法,它是平方和的倍数...很抱歉,但我不知道详细信息。