简体   繁体   English

根据模式切换int数组中的数字

[英]Switch numbers in int array according to a pattern

I've been scanning the internet trying to come up with a solution for this simple program that will basically take user input in numbers (a telephone number) and change every number according to the following rules: 我一直在扫描互联网,试图为这个简单的程序提出一个解决方案,基本上用户输入数字(电话号码)并根据以下规则更改每个数字:

0 → (becomes) 5, 1 → 9, 2 → 8, 3 → 7, 4 → 6, 5 → 0, 6 → 4, 7 → 3, 8 → 2, 9 → 1. 0→(变为)5,1→9,2→8,3,4,4→6,5→0,6→4,7→3,8→2,9→1。

So a number of 7784321600 becomes 3326789455. 所以7784321600的数量变为3326789455。

I took user input as a String, converted it to an int array but when I try to swap, I don't get it to work as well as I hoped for. 我将用户输入作为String,将其转换为int数组但是当我尝试交换时,我不能让它像我希望的那样工作。

I tried to swap the values with the in the following way: 我试图用以下方式交换值:

for (int i = 0; i < input.length(); i++) {
    if (nrArray[i] == 0) {
        // 0 becomes 5
        int temp0[] = { 5 };
        nrArray[i] = nrArray[i] + temp0[i];
        temp0[i] = nrArray[i] - temp0[i];
        nrArray[i] = nrArray[i] - temp0[i];
    }
}

which works OK if it was only going to swap numbers 0-4, as soon as it reaches 5-9, the code will reverse it again like this: 如果它只是交换数字0-4就可以正常工作,一旦它达到5-9,代码将再次反转它,如下所示:

for (int i = 0; i < input.length(); i++) {
    if (nrArray[i] == 5) {
        // 5 becomes 0
        int temp0[] = { 0 };
        nrArray[i] = nrArray[i] + temp0[i];
        temp0[i] = nrArray[i] - temp0[i];
        nrArray[i] = nrArray[i] - temp0[i];
    }
}

I also tried the replaceAll method for changing the string, but the same problem occurs. 我也尝试使用replaceAll方法来更改字符串,但是会出现同样的问题。

Any suggestions? 有什么建议么?

All the answers so far have focused on giving you code that will work; 到目前为止,所有答案都集中在为您提供可行的代码; none of them on telling you why your current code doesn't work. 没有人告诉你为什么你当前的代码不起作用。

The structure of what you've got is something like this: 你得到的结构是这样的:

if (a[i]==0) { a[i]=somefixedvalue }
if (a[i]==1) { a[i]=someothervalue }
if (a[i]==2) { a[i]=somethirdvalue }
//etc.

The problem here is that all your statements get executed, one by one. 这里的问题是你的所有语句都是逐个执行的。 If the first one changes the value of a[i] to a 1, then the second one will also pass the guard and change it again. 如果第一个将a[i]的值更改为1,则第二个也将通过保护并再次更改它。

What you really want is to say that the first statement whose guard matches should be executed, and after that it should stop. 你真正想要的是说应该执行其后卫匹配的第一个语句,然后它应该停止。 The right pattern for that would be 正确的模式是

if (a[i]==0) { a[i]=somefixedvalue }
else if (a[i]==1) { a[i]=someothervalue }
else if (a[i]==2) { a[i]=somethirdvalue }
//etc.

There are neater approaches to a solution, including storing a fixed map, or using a switch statement, but hopefully this answers your question as to why your code doesn't work as it stands. 有一些更简洁的解决方案,包括存储固定的地图,或使用switch语句,但希望这可以回答你的问题,为什么你的代码不能正常工作。

One simple solution would be having a fixed map : 一个简单的解决方案是拥有固定的地图

{0: 5, 1: 9, 2: 8, 3: 7, 4: 6, 5: 0, 6: 4, 7: 3, 8: 2, 9: 1}

Then you simply iterate on the sequence, and for each character ch , you replace it with map[ch] . 然后你只需迭代序列,对于每个字符ch ,你用map[ch]替换它。

The solution's complexity is O(n), the best you can have. 解决方案的复杂性是O(n),你可以拥有的最好。


Pseudo code: 伪代码:

res = ""
for ch in seq:
    res += map[ch]

Use a hashmap to store source integer as key and target integer as value. 使用散列映射将源整数存储为键,将目标整数存储为值。 Then iterate through the array, during each iteration get the current array value target from hashmap and replace it. 然后迭代遍历数组,在每次迭代期间从hashmap获取当前数组值目标并替换它。

int a[] = {7,7,8,4,3,2,1,6,0,0};
Map<Integer, Integer> map = new HashMap<Integer, Integer>();

//0->5, 1->9, 2->8, 3->7, 4->6, 5->0, 6->4, 7->3, 8->2, 9->1
map.put(0, 5);
map.put(1, 9);
map.put(2, 8);
map.put(3, 7);
map.put(4, 6);
map.put(5, 0);
map.put(6, 4);
map.put(7, 3);
map.put(8, 2);
map.put(9, 1);

for (int i = 0; i < a.length; i++) {
    a[i] = map.get(a[i]);
}

Using an integer array, you can create a cheap and fast map, which you can use to map your input <-> your desire input. 使用整数数组,您可以创建一个便宜且快速的地图,您可以使用它来映射输入< - >您的愿望输入。 Also, using a stringbuilder you can create a string representation of the number, and then parse it to int 此外,使用stringbuilder,您可以创建数字的字符串表示形式,然后将其解析为int

int [] switcher = {5,9,8,7,6,0,4,3,2,1};

    int [] input;
    StringBuilder wholeNumber = new StringBuilder();
    for(int i = 0; i < input.length; i++)
    {
        input[i] = switcher[input[i]];
        wholeNumber.append(String.valueOf(input[i]));
    }

    int wholeNumberInt = Integer.parseInt(wholeNumber.toString());

You can also use a Switch statement that replaces each array element to reach your goal. 您还可以使用Switch语句替换每个数组元素以实现目标。 This example checks each element and replaces it with the correct digit then prints out the resulting array. 此示例检查每个元素并用正确的数字替换它,然后打印出结果数组。

    int arr[] = {4,0,7,8,8,5,0,0,9,0};
    for(int i=0; i<arr.length;i++){
        switch(arr[i]){
            case 0:
                arr[i] = 5;
                break;
            case 1:
                arr[i] = 9;
                break;
            case 2:
                arr[i] = 8;
                break;
            case 3:
                arr[i] = 7;
                break;
            case 4:
                arr[i] = 6;
                break;
            case 5:
                arr[i] = 0;
                break;
            case 6:
                arr[i] = 4;
                break;
            case 7:
                arr[i] = 3;
                break;
            case 8:
                arr[i] = 2;
                break;
            case 9:
                arr[i] = 1;
                break;
            }
    }
    for(int i =0; i<arr.length;i++) {
        System.out.println(arr[i]);
    }
}

in your case you can use the following Condition 在您的情况下,您可以使用以下条件

   if(nrArray[i]%5 == 0) {
     nrArray[i]= 5-nrArray[i];
    }
   else{
     nrArray[i]= 10-nrArray[i];
    }

Have only one for loop, containing all the number switches in if-else statements. 只有一个for循环,包含if-else语句中的所有数字开关。 The loop will only run once for each number in the array and therefore wont change the 5 to a 0 and back to a 5 again, like yours is doing. 循环只会对数组中的每个数字运行一次,因此不会将5更改为0并再次返回到5,就像您所做的那样。

for(int i=0; i<input.length(); i++){
    if(nrArray[i]==0){
        nrArray[i]=5;
    }else if(nrArray[i]==5){
        nrArray[i]=0;
    }//All the other else-if for the different number switches
}

Because you use an else if statement, only one block will run for each number in the array. 因为您使用else if语句,所以只会为数组中的每个数字运行一个块。

Since it's not a logical split (ie 0 <-> 9 ; 1 <-> 8 ; 2 <-> 7 ; 3 <-> 6 ; 4 <-> 5 ), I think a possible choice would be to use a map like this: 由于它不是逻辑分裂(即0 <-> 9 ; 1 <-> 8 ; 2 <-> 7 ; 3 <-> 6 ; 4 <-> 5 ),我认为可能的选择是使用地图像这样:

import java.util.HashMap;
import java.util.Map;

public class Main
{
    private static final Map<Character, Character> map = new HashMap<Character, Character>() {
        private static final long serialVersionUID = 1L;

        {
            put('0', '5');
            put('1', '9');
            put('2', '8');
            put('3', '7');
            put('4', '6');
            put('5', '0');
            put('6', '4');
            put('7', '3');
            put('8', '2');
            put('9', '1');
        }
    };

    public static void main(final String[] args) {

        final String aNumber = "7784321600";

        char[] list = aNumber.toCharArray();
        String result = "";
        for (final char ch : list) {
            result += map.get(ch);
        }

        System.out.println("Before: " + aNumber);
        System.out.println("After: " + result);
    }
}

Output: 输出:

Before: 7784321600
After: 3326789455

IF you want something nice and simple... You could store input in an int array and do this 如果你想要一些简单明了的东西......你可以将输入存储在一个int数组中并执行此操作

int[] input = {1, 2, 3, 4, 5, 6, ,7 ,8, 9, 0};
int[] encoded = new int[input.length];

for(int i=0; i < encoded.length; i++)
{
    if (input[i] == 5)
    {
      encoded[i] = 0;
      continue;
    }

    if (input[i] == 0)
    {
      encoded[i] = 5;
      continue;
    }

    encoded[i] = 10 - input[i]; 
}

Your encoding seems to follow a pattern except 0 and 5. I see no need to map all the values. 您的编码似乎遵循除0和5之外的模式。我认为不需要映射所有值。 You just need to map the ones that don't fit the pattern. 您只需要映射那些不适合模式的那些。

One of the solutions with complexity O(n) is to simply store the new values in an array and replace it with your input tape while iterating it. 复杂度为O(n)的解决方案之一是将新值简单地存储在数组中,并在迭代时将其替换为输入磁带。

I took user input as a String, converted it to an int array 我将用户输入作为String,将其转换为int数组

There is no explicit need of converting your input String to the int array. 没有明确需要将输入String转换为int数组。

Here is the code snippet: 这是代码片段:

public static void main (String[] args) throws Exception {
    int[] arr = {5,9,8,7,6,0,4,3,2,1};
    String input = "7784321600";
    for(char c : input.toCharArray()) {
        System.out.print(arr[Character.getNumericValue(c)]);
    }
    System.out.println();
}

Output: 输出:

3326789455

I believe that this is what you are aiming at. 我相信这就是你的目标。

Just use the value of the current number as the index of the key array. 只需使用当前数字的值作为键数组的索引。 This will find its respective value to convert to. 这将找到它转换为的相应值。

public class NumberEncoder {
    private static final int[] KEY = { 5, 9, 8, 7, 6, 0, 4, 3, 2, 1 };

    public static void main(String[] args) {
        System.out.println(encode(125, KEY)); // 980
    }

    public static int encode(int n, int[] key) {
        String input = Integer.toString(n);
        StringBuffer result = new StringBuffer();

        for (int i = 0; i < input.length(); i++) {
            result.append(key[Character.getNumericValue(input.charAt(i))]);
        }

        return Integer.parseInt(result.toString());
    }
}

If you need to handle larger numbers which are greater than a long value, you can use BigInteger . 如果需要处理大于long值的较大数字,可以使用BigInteger

import java.math.BigInteger;

public class NumberEncoder {
    private static final int[] KEY = { 5, 9, 8, 7, 6, 0, 4, 3, 2, 1 };

    public static void main(String[] args) {
        System.out.println(encode(new BigInteger("123456789012345678901234567890"), KEY));
    }

    public static BigInteger encode(BigInteger value, int[] key) {
        String input = value.toString();
        StringBuffer result = new StringBuffer();

        for (int i = 0; i < input.length(); i++) {
            result.append(key[Character.getNumericValue(input.charAt(i))]);
        }

        return new BigInteger(result.toString()); // 987604321598760432159876043215
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM