【问题标题】:Java incrementing every character in a string by a large amount?Java大量增加字符串中的每个字符?
【发布时间】:2014-05-10 01:21:40
【问题描述】:

目前我有一个程序要求输入字符串,例如“Hello stackoverflow!”我试图让它增加一个大的随机数。问题是,一旦程序到达'~',它就必须开始倒退,然后一旦它到达'!',它就必须再次切换。 (! 是第一个 Ascii 符号,~ 是最后一个,中间有数字和字母。)到目前为止,这就是我所拥有的递增部分,但它并不完全有效:

for(int i = 0; i < inputStringB.length(); i++){
    currentChar = inputString.charAt(i);

    for(int e = 0; e < 1000; e++){

        if(currentChar == '!'){
            switchIncrement = 1;
        } else if(currentChar == '~') {
            switchIncrement = 0;
        }

        switch(switchInc){
            case 0: currentChar--;
                inputStringB.setCharAt(i, currentChar);
                break;
            case 1: currentChar++;
                inputStringB.setCharAt(i, currentChar);
                break;
            default:  currentChar++;
                inputStringB.setCharAt(i, currentChar);
                break;
        }
    }               
    System.out.println(inputStringB);   
}

当我输入'Hello' 时,我收到:'n#J&amp;)' 考虑到'Hello' 包含两个l,这是没有意义的,所以我希望'n#JJ)'

任何帮助都会很棒,谢谢!

完整代码:

  import java.util.Scanner;
public class EncryptionMain {
    public static void main(String args[]){

        char currentChar;
        String EorD;
        int switchInc = 1; // 0 = BACK 1 = FORWARD 
        Scanner scanner = new Scanner(System.in);

        System.out.println("Encrypt or decrypt: ");

        EorD = scanner.next();

        if(EorD.equalsIgnoreCase("e")){

            System.out.println("Please enter text to encrypt: ");

            String inputString = scanner.next();

            System.out.println("Encrypting: '" + inputString + "' ");
            System.out.println("...");
            System.out.println("...");
            System.out.println("...");
            StringBuilder inputStringB = new StringBuilder(inputString);
            for(int i = 0; i < inputStringB.length(); i++){
                currentChar = inputStringB.charAt(i);
                System.out.println(currentChar);
                for(int e = 0; e < 1000; e++){

                        if(currentChar == '!'){
                            switchInc = 1;
                        }else if(currentChar == '~'){
                            switchInc = 0;
                        }

                        switch(switchInc){

                        case 0: currentChar--;
                                inputStringB.setCharAt(i, currentChar);
                                break;

                        default:  currentChar++;
                                  inputStringB.setCharAt(i, currentChar);
                                  break;
                        }
                }

                System.out.println(inputStringB);   
            }
        }else if(EorD.equalsIgnoreCase("d")){

            System.out.println("Please enter text to decrypt: ");

            String inputString = scanner.next();

            System.out.println("Decrypting: '" + inputString + "' ");
            System.out.println("...");
            System.out.println("...");
            System.out.println("...");
            StringBuilder inputStringB = new StringBuilder(inputString);
            for(int i = 0; i < inputStringB.length(); i++){
                currentChar = inputStringB.charAt(i);

                for(int e = 0; e < 1000; e++){
                    if(currentChar == '!'){
                            switchInc = 0;
                    }else if(currentChar == '~'){
                            switchInc = 1;
                    }
                        switch(switchInc){
                        case 0: currentChar++;
                                inputStringB.setCharAt(i, currentChar);
                                break;
                        case 1: currentChar--;
                                inputStringB.setCharAt(i, currentChar);
                                break;
                        default:  currentChar--;
                                  inputStringB.setCharAt(i, currentChar);
                                  break;
                        }
                }

                inputStringB.setCharAt(i, currentChar);
                System.out.println(inputStringB);   
            }
        }

    }
}

【问题讨论】:

  • 那么你做了什么来调试它?
  • 您的案例 1 不需要。默认值做同样的事情,如果没有明确的 1 情况,它会抓住它。
  • “随机数”从何而来?我在你给出的代码中没有看到任何随机性。
  • @ChrisMartin 我打算补充一点,一旦我解决了主要问题,我可能不应该这么说。
  • 这将有助于发布编译代码。所有这些变量都未声明:inputStringBinputStringcurrentCharswitchIncrementswitchInc

标签: java loops


【解决方案1】:

首先我要移除所有的 I/O(除了输出结果),为了简洁起见去掉解密部分,将encrypt(String)encrypt(char) 写成pure functions

public class EncryptionMain {

    public static void main(String args[]){
        System.out.println(encrypt("Hello"));
    }

    static String encrypt(String plaintext) {
        StringBuilder ciphertext = new StringBuilder(plaintext);
        for (int i = 0; i < ciphertext.length(); i++) {
            ciphertext.setCharAt(i, encrypt(ciphertext.charAt(i)));
        }
        return ciphertext.toString();
    }

    static char encrypt(char c) {
        int switchInc = 1; // 0 = BACK 1 = FORWARD

        for(int e = 0; e < 1000; e++){
            if (c == '!') {
                switchInc = 1;
            } else if (c == '~') {
                switchInc = 0;
            }

            switch (switchInc) {
                case 0: c--; break;
                default: c++; break;
            }
        }
        return c;
    }
}

还有,哎呀! - 只是这样做,我不小心修复了这个错误。在这里,我将其添加回来:

public class EncryptionMain {

    public static void main(String args[]){
        System.out.println(encrypt("Hello"));
    }

    static String encrypt(String plaintext) {
        StringBuilder ciphertext = new StringBuilder(plaintext);
        for (int i = 0; i < ciphertext.length(); i++) {
            ciphertext.setCharAt(i, encrypt(ciphertext.charAt(i)));
        }
        return ciphertext.toString();
    }

    static int switchInc = 1; // 0 = BACK 1 = FORWARD

    static char encrypt(char c) {

        for(int e = 0; e < 1000; e++){
            if (c == '!') {
                switchInc = 1;
            } else if (c == '~') {
                switchInc = 0;
            }

            switch (switchInc) {
                case 0: c--; break;
                default: c++; break;
            }
        }
        return c;
    }
}

编辑 - 这是我在下面的 cmets 中提到的一个有效的凯撒密码。

main/cipher/Cipher.java

package cipher;

public final class Cipher {

    public Cipher(Range range, int key) {
        this.range = range;
        this.key = key;
    }

    public final Range range;
    public final int key;

    public String encrypt(String plaintext) {
        return cipher(plaintext, key);
    }

    public String decrypt(String ciphertext) {
        return cipher(ciphertext, -key);
    }

    String cipher(String in, int n) {
        StringBuilder out = new StringBuilder(in.length());
        for (int i = 0; i < in.length(); i++) {
            out.append(range.shift(in.charAt(i), n));
        }
        return out.toString();
    }
}

main/cipher/Range.java

package cipher;

public final class Range {

    public final char min;
    public final char max;
    public final int size;

    public static Range inclusive(char min, char max) {
        return new Range(min, max);
    }

    Range(char min, char max) {
        this.min = min;
        this.max = max;
        size = max - min + 1;
    }

    /** Shift c up by i places, wrapping around to the
     * beginning of the range when it reaches the end. */
    public char shift(char c, int i) {
        return (char) (min + mod(c - min + i, size));
    }

    /** x mod a */
    static int mod(int x, int a) {
        return ((x % a) + a) % a;
    }
}

test/cipher/CipherTest.java

package cipher;

import org.testng.annotations.Test;

import static org.testng.Assert.assertEquals;

public class CipherTest {

    @Test
    public void testZeroKey() throws Exception {
        Cipher cipher = new Cipher(Range.inclusive('a', 'z'), 0);
        assertEquals(cipher.encrypt("abcxyz"), "abcxyz");
        assertEquals(cipher.decrypt("abcxyz"), "abcxyz");
    }

    @Test
    public void testOneKey() throws Exception {
        Cipher cipher = new Cipher(Range.inclusive('a', 'z'), 1);
        assertEquals(cipher.encrypt("abcxyz"), "bcdyza");
        assertEquals(cipher.decrypt("bcdyza"), "abcxyz");
    }

    @Test
    public void testSizePlusOneKey() throws Exception {
        Cipher cipher = new Cipher(Range.inclusive('a', 'z'), 27);
        assertEquals(cipher.encrypt("abcxyz"), "bcdyza");
        assertEquals(cipher.decrypt("bcdyza"), "abcxyz");
    }
}

test/cipher/RangeTest.java

package cipher;

import org.testng.Assert;
import org.testng.annotations.Test;

import static org.testng.Assert.assertEquals;
import static cipher.Range.mod;

public class RangeTest {

    @Test
    public void testSize() {
        Assert.assertEquals(Range.inclusive('a', 'c').size, 3);
    }

    @Test
    public void testMod() throws Exception {
        assertEquals(mod(-2, 5), 3);
        assertEquals(mod(-1, 5), 4);
        assertEquals(mod(0, 5), 0);
        assertEquals(mod(1, 5), 1);
        assertEquals(mod(2, 5), 2);
        assertEquals(mod(3, 5), 3);
        assertEquals(mod(4, 5), 4);
        assertEquals(mod(5, 5), 0);
        assertEquals(mod(6, 5), 1);
    }

    @Test
    public void testShift() throws Exception {
        Range r = Range.inclusive('a', 'd');
        Assert.assertEquals(r.shift('a', -2), 'c');
        Assert.assertEquals(r.shift('a', -1), 'd');
        Assert.assertEquals(r.shift('a', 0), 'a');
        Assert.assertEquals(r.shift('a', 1), 'b');
        Assert.assertEquals(r.shift('a', 2), 'c');
        Assert.assertEquals(r.shift('a', 3), 'd');
        Assert.assertEquals(r.shift('a', 4), 'a');
        Assert.assertEquals(r.shift('a', 5), 'b');
    }
}

【讨论】:

  • 哇,通过提问我学到了很多东西,喜欢这个网站。但是你能告诉我我的代码有什么问题吗?我还是不知道。
  • 我还注意到一件事,如果你在 for 循环中有一个很大的数字,“int e = 0; e
  • 在我的回答中仔细看两个版本的区别。区别在于switchInc 的范围。每次加密字符时,该变量都需要初始化为1。您不能共享该变量,而只能使用它从上一次迭代中留下的任何值。
  • 更具体地了解“不起作用”是什么意思?对我来说,这似乎很好(尽管效率很低)。
  • 对不起,我没有具体说明我很着急。我的意思是如果我加密: "abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()`~-_=+[{]};':",./?|\" 我得到的输出是:" UTSRQPONMLKJIHGFEDCBA@?>=
猜你喜欢
  • 1970-01-01
  • 2015-06-18
  • 1970-01-01
  • 2021-10-04
  • 2018-05-26
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 2021-01-11
相关资源
最近更新 更多