我正在努力解决问题。希望在这里得到一些帮助。
目标:找到一个紧邻输入的数字,其中只包含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
}
答案 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`
如果数字中的所有数字都是4
或7
,则此方法无效。您需要有一个条件并相应地更改一个或两个字符。
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;并从左到右检查每个数字。
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; 对于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
以来的价值。
考虑案例Xcccccccc
,c
是任何值
X in {4,7}
,请考虑案例2. X in {1,2,3}
,则下一个值应为444444444
。X in {5,6}
,则下一个值应为744444444
。X in {8,9}
,则下一个值应为4444444444
考虑案例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}
,则下一个值应为bbbb44444
或bbbbb44444
。(b为&#34; 4&#34;或&#34; 7&#34;)
bbbb
或bbbbb
?
aaaa does not have any "4"
,则获得bbbbb = 44444
(因为aaaa = 7777)aaaa have "4"
,则会bbbb
(&#34; 4&#34;将替换为&#34; 7&#34;,例如474779 =&gt; 477444)考虑案例aaaaaaaaX
,这应该与案例2相同,但不需要处理剩余的数字
结合案例1-3,当第一次出现非&#34;&#34; /&#34; 7&#34;数字在{8,9},数值变化的差异取决于是否有任何&#34; 4&#34;在数字之前。