找到具有特定模式的给定输入的下一个最大数字

时间:2014-09-19 04:37:25

标签: java algorithm math numbers pattern-matching

我正在努力解决问题。希望在这里得到一些帮助。

目标:找到一个紧邻输入的数字,其中只包含4和7。

Input : 1234
Output: 4444

Input : 4476
output: 4477

Input  : 8327
Output : 44444

我不是在寻找递增数字,而是每次检查模式的字符串字符。对于大数字来说,这太慢了。

static String toOutput (int a) {
    // I am trying here all the possible other ways
}

9 个答案:

答案 0 :(得分:3)

检查这个答案。希望这会有所帮助:)

private static String toOutput(int n) {

    String input = String.valueOf(n+1);

    // create input character array and output character array of one more in size
    char[] inputChars = input.toCharArray();
    char[] outputChars = new char[inputChars.length + 1];

    boolean extra = false; //carry forward

    // traverse input array from last position to first position
    for (int i = inputChars.length - 1; i >= 0; i--) {
        // for all other positions except last position check whether number is changed
        // (i.e. apart from 4 or 7), 
        // change all higher digits in output array to 4
        if ((i + 1) < inputChars.length) {
            if (inputChars[i] != '4' && inputChars[i] != '7') {
                for (int j = i + 1; j < inputChars.length; j++) {
                    outputChars[j + 1] = '4';
                }
            }
        }

        // if extra is true that means it is carry forward
        if (extra == true) {
            inputChars[i] = (char) ((int) inputChars[i] + 1);
        }

        // if input digit is less than equal to 4 output digit is 4 , extra is false
        if (inputChars[i] <= '4') {
            outputChars[i + 1] = '4';
            extra = false;

        } 
        // if input digit is between 4 to 7 output digit is 7 , extra is false
        else if (inputChars[i] <= '7') {
            outputChars[i + 1] = '7';
            extra = false;

        } 
        // if input digit is more than 7 output digit is 4 , extra is true 
        else {
            outputChars[i + 1] = '4';
            extra = true;
        }

    }

    // if carry forward is true, make extra digit to 4 otherwise it is not required
    if (extra == true) {
        outputChars[0] = '4';

    } else {
        outputChars[0] = ' ';
    }

    return new String(outputChars).trim();
}

答案 1 :(得分:2)

由于这基本上是对字符串的操作,因此合理的解决方案是使用字符串函数,尤其是正则表达式。这是一个紧凑的解决方案:

class Incrementer {
  Pattern p;
  public Incrementer() {
    p = Pattern.compile("(?:([47]*)([0-6]))?(.*)");
  }
  public String next(String s) {
    Matcher m = p.matcher(s);
    m.lookingAt();
    return (m.group(1)==null
              ? '4'
              : m.group(1) + (m.group(2).charAt(0) >= '4' ? '7' : '4'))
           + m.group(3).replaceAll(".", "4");
  }
}

here

(我根本不是Java程序员。欢迎编码建议。)

正则表达式匹配任何合法数字序列(4或7)的前缀,后跟可递增的数字(&lt; 7)。如果该前缀不匹配,则答案必须长一位,因此必须以最小的合法数字(4)开头。如果前缀是可匹配的,则必须通过将最后一个数字碰到下一个合法数字来修改前缀。在这两种情况下,(可能为空)前缀后面的所有数字都将替换为最小的合法数字。

当然,这可以在没有实际正则表达式的情况下完成。以下主要使用实现正则表达式的状态机,因此它可能更快。 (我个人认为正则表达式更容易验证,但是YMMV):

public static String next(String s)
{
    int toinc = -1;
    for (int i = 0; i < s.length(); ++i) {
        char c = s.charAt(i);
        if (c < '7') {
            toinc = i;
            if (c != '4') break;
        } else if (c > '7') break;
    }
    char[] outChars;
    // Copy the prefix up to and including the character to be incremented
    if (toinc < 0) {
        outChars = new char[s.length() + 1];
    } else {
        outChars = new char[s.length()];
        for (int i = 0; i < toinc; ++i)
            outChars[i] = s.charAt(i);
        // Increment the character to be incremented
        outChars[toinc] = s.charAt(toinc) >= '4' ? '7' : '4';
    }
    // Fill with 4's.
    for (int i = toinc + 1; i < outChars.length; ++i)
        outChars[i] = '4';
    return new String(outChars);
}

here

答案 2 :(得分:2)

static String toOutput (long a) {

    LinkedList<Long> q = new LinkedList<Long>();
    q.add(4L);
    q.add(7L);
    while(!q.isEmpty()){
        Long curr = q.pop();
        if(curr>a)
            return String.valueOf(curr);
        q.add(curr*10+4);
        q.add(curr*10+7);
    }
    return "";
}

这将解决接近O(LogN)

的问题

答案 3 :(得分:1)

*

public class PatternTest {
    private static final char FOUR = '4';
    private static final char SEVEN = '7';
    public static void main(String[] args) {
        Scanner scanner = new Scanner(new InputStreamReader(System.in));
        String value = scanner.next();
        char startChar = value.charAt(0);
        Result result;
        if (startChar == FOUR || startChar == SEVEN) {
            result = getStartWith4Or7(value);
        } else {
            result = getNotStartWith4Or7(value);
        }
        System.out.println("Final value is : " + result.getValue());
    }
    private static Result getNotStartWith4Or7(String value) {
        Result result = new Result();
        char startChar = value.charAt(0);
        if (startChar < FOUR) {
            result.value = value.replaceAll(".", String.valueOf(FOUR));
        } else if (startChar > SEVEN) {
            result.value = value.replaceAll(".", String.valueOf(FOUR));
            result.flag = FOUR;
        } else if (startChar > FOUR && startChar < SEVEN) {
            result.value = getSubString(value).replaceAll(".", String.valueOf(FOUR));
            result.value = String.valueOf(SEVEN) + result.value;
        }
        return result;
    }
    private static Result getStartWith4Or7(String value) {
        Result result = new Result();
        if (value != null && !value.equalsIgnoreCase("")) {
            char startChar = value.charAt(0);
            if (startChar == FOUR || startChar == SEVEN) {
                value = getSubString(value);
                result = getStartWith4Or7(value);
                result.value = getStartCharUpdate(startChar, result) + result.value;
            } else {
                result = getNotStartWith4Or7(value);
            }
        }
        return result;
    }
    private static String getStartCharUpdate(char startChar, Result result) {
        String newValue = String.valueOf(startChar);
        if (result.flag == FOUR) {
            if (startChar == FOUR) {
                newValue = String.valueOf(SEVEN);
                result.flag = 0;
            } else {
                newValue = String.valueOf(FOUR);
            }
        }
        return newValue;
    }
    private static String getSubString(String value) {
        int len = value.length();
        String finalValue = "";
        if (len > 1) {
            finalValue = value.substring(1, len);
        }
        return finalValue;
    }
    static class Result {
        String value = "";
        char flag;
        public String getValue() {
            if (flag == FOUR) {
                value = FOUR + value;
            }
            return value;
        }
    }
}

*

答案 4 :(得分:0)

一种方法是从右到左读取数字,检查是否小于4或7,分别加4或7。

如果第一个(从左侧)数字是>7,那么将检查一个优化,然后确定您将拥有所有4's + 1个额外4个。

您需要特别注意最左边的数字。如果最左边的数字大于7,则需要添加两个4。

EX: 1234
right to left `4` is `4`
              `3` is `4`
              `2` is `4`
              `1` is `4`

如果数字中的所有数字都是47,则此方法无效。您需要有一个条件并相应地更改一个或两个字符。

private static String toOutput(int a) {
        String s = Integer.toString(a);
        StringBuilder sb = new StringBuilder();
        if (Integer.valueOf(s.charAt(0)) > 7) {
            for(int i=0; i<= s.length(); i++) {
                sb.append("4");
            }
            return sb.toString();
        }
        for(int i=s.length()-1; i>=0; i--) {
            Integer x = Integer.valueOf(i);

            if(x <=4) {
                sb.append(4);
            } else {
                sb.append(7);
            }
        }
        return sb.reverse().toString();
    }

这不是检查号码是否包含全部4或7。

答案 5 :(得分:0)

你可以尝试这样的事情。

 String num = "4476";
 double immediateVal = 0;
 int length = num.length();
 StringBuilder sb1 = new StringBuilder();
 StringBuilder sb2 = new StringBuilder();
  for (int i = 0; i < length; i++) {
      sb1.append("4");
      sb2.append("7");
  }
 double valNum = Double.parseDouble(num);
 double val1 = Double.parseDouble(sb1.toString());
 double val2 = Double.parseDouble(sb2.toString());
  if (valNum < val1) {
     immediateVal = val1;
   } else if (val1 <= valNum && valNum < val2) {
      if(num.indexOf("4")==0){
         int firstIndexOf7=-1;
          for(int a=0;a<length;a++){
             firstIndexOf7=num.indexOf("7");
             if(firstIndexOf7!=-1){
                break;
              }
         }
        if(firstIndexOf7!=-1){
            StringBuilder sb3=new StringBuilder();
             for(int b=0;b<firstIndexOf7;b++){
                 sb3.append("4");
              }
             for(int b=firstIndexOf7;b<length;b++){
                 sb3.append("7");
              }
             immediateVal=Double.parseDouble(sb3.toString());
            }
       } else{
          immediateVal = val2;
       }
  }else if(valNum>=val2){
     immediateVal=Double.parseDouble(sb1.append("4").toString());
  }
  System.out.println(immediateVal);

答案 6 :(得分:0)

我认为您不必担心将数字转换为字符串的性能。您正在评估一个数字,就好像它是一个字符串一样,所以只有将其转换为字符串才能进行评估。

这样的事情很有效,并且相当快。

  public static int closestNumber(int num) {
    for (int i = num + 1; i < Integer.MAX_VALUE; i++) {
      if ((i+"").matches("^[47]+$")) {
        return i;
      }
    }
    throw new RuntimeException("Your number was too close to Integer's max value!");
  }

好的,我是用mod编写的,没有字符串:

  public static int closestNumber(int num) {
    for (int i = num + 1; i < Integer.MAX_VALUE; i++) {
      if (containsOnly(i,4,7)) {
        return i;
      }
    }
    throw new RuntimeException("Your number was too close to Integer's max value!");
  }

  public static boolean containsOnly(int evaluate, int numeralA, int numeralB) {
    while (evaluate > 0) {
      int digit = evaluate % 10;
      if (digit != numeralA && digit != numeralB) return false;
      evaluate = evaluate / 10;
    }
    return true;
  }

答案 7 :(得分:0)

这可以帮到你

static String toOutput(String input){
    char[] values = input.toCharArray();
    StringBuilder result = new StringBuilder();
    int length = values.length;
    int currentPosition = 0;
    for(char current: values){
        Integer currentInt = new Integer(current);
        if(currentInt<4){
            //fill the string with 4, best result
            for(currentPosition;currentPosition<length;currentPosition++){
                result.append(4);
            }
            break;
        }
        else if(currentInt==4){
            result.append(4);
            currentPosition++;
            continue;
        }
        else if(currentInt<=7){
            result.append(7);
            currentPosition++;
            continue;
        }
        else if(currentInt>7){
            if(currentPosition=0){
               //fill the string with 4 but with length +1, best result
               for(currentPosition;currentPosition<=length;currentPosition++){
                    result.append(4);
               }
               break;
            }
            else{
               // you need work this case, change last 4 to 7 and fill the rest with 4. enjoy it.
            }
       }
    return result.toString();

}

答案 8 :(得分:0)

它看起来像是从左到右查找不是4或7的第一个数字。

设置索引指针以记录保存数字的最后一个索引&#34; 4&#34;并从左到右检查每个数字。

  1. 初始当前指针索引(c)为-1并设置为最后一个&#34; 4&#34; index(l)to -1
  2. 对于从左到右的每个数字
    • 更新c(c+=1
    • 检查数字值
      • digit = 7 - &gt;什么都不做
      • digit = 4 - &gt; l = c
      • digit < 4 - &gt;此数字更改为&#34; 4&#34;,所有剩余数字设置为&#34; 4&#34;,结束检查
      • 4 < digit < 7 - &gt;此数字更改为&#34; 7&#34;,所有剩余数字设置为&#34; 4&#34;,结束检查
      • digit > 7 - &gt;做必要的改变和结束检查
        • l = -1 =&gt; 444....444 (no. of digit = n+1)
        • l > -1 =&gt; l处的数字变为&#34; 7&#34;,l后的所有数字变为&#34; 4&#34;
  3. 对于n位数值,如果它仅包含&#34; 4&#34;或&#34; 7&#34;,你什么都不做。 然后,如果有任何非&#34; 4&#34;或&#34; 7&#34;,应该是什么?

    分析模式,我们需要知道第一次出现非&#34; 4&#34; /&#34; 7&#34;仅数字(从左到右),数字后的所有数字将变为&#34; 4&#34;最小化自444...444 is the least k-digit value for combination of "4" and "7" for all k以来的价值。

    1. 考虑案例Xccccccccc是任何值

      • 如果X in {4,7},请考虑案例2.
      • 如果X in {1,2,3},则下一个值应为444444444
      • 如果X in {5,6},则下一个值应为744444444
      • 如果X in {8,9},则下一个值应为4444444444
    2. 考虑案例aaaaXcccc,如果a是&#34; 4&#34;或&#34; 7&#34;

      • 如果X in {4,7},请考虑案例aaaaaXccc
      • 如果X in {0,1,2,3},则下一个值应为aaaa44444
      • 如果X in {5,6},则下一个值应为aaaa74444
      • 如果X in {8,9},则下一个值应为bbbb44444bbbbb44444。(b为&#34; 4&#34;或&#34; 7&#34;)
        • 然后如何推断bbbbbbbbb
          • 如果aaaa does not have any "4",则获得bbbbb = 44444(因为aaaa = 7777)
          • 如果aaaa have "4",则会bbbb(&#34; 4&#34;将替换为&#34; 7&#34;,例如474779 =&gt; 477444)
    3. 考虑案例aaaaaaaaX,这应该与案例2相同,但不需要处理剩余的数字

    4. 结合案例1-3,当第一次出现非&#34;&#34; /&#34; 7&#34;数字在{8,9},数值变化的差异取决于是否有任何&#34; 4&#34;在数字之前。