1

我现在一直在尝试不同的事情,但我无法弄清楚为什么我的逻辑是错误的。这没有意义。

我正在尝试基于以下伪代码制作程序。


将以下用于随机排列字符串中的字符的伪代码翻译成 Java 程序。

  1. 读一个字。
  2. 重复循环 word.length() 次
  3. 在单词中选择一个随机位置 i,但不是最后一个位置。
  4. 在单词中选择一个随机位置 j > i。
  5. 交换位置 j 和 i 的字母。
  6. 打印单词。
  7. 然后将字符串替换为:first + word.charAt(j) + middle + word.charAt(i) + last

这是我到目前为止所拥有的:

package assignment4;

import java.util.Scanner;

public class P4Point7 {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);

        System.out.print("Please enter a word: ");
        String word = in.next();
        in.close();

        int wordLength = word.length(); // Gets the word.Length
        int x = 1; // Primes the loop

        while (x <= wordLength) {
            int i = (int) ((Math.random() * wordLength) - 1); // Gets a random letter i that is not the last letter
            int j = (int) (Math.random() * (wordLength - i)) + i; // Gets a random letter j after i 
            String first = word.substring(0, i); // Gets first part of word
            String middle = word.substring(i + 1, j); // Gets middle part of word
            String last = word.substring(j + 1, wordLength); // Gets last part of word
            x++; // Increments the loop
            String status = first + word.charAt(j) + middle + word.charAt(i) + last; // Swaps i and j in the word
            System.out.println(status);
        }   
    }
}

我遇到的问题是

Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(Unknown Source)
at assignment4.P4Point7.main(P4Point7.java:21)

我正在用“Waffle”这个词测试程序。

4

6 回答 6

1

几个建议:

使用Random对象生成随机索引可以简化索引生成。Math.random()返回 0.0 到 1.0 之间的双精度值。不保证将其乘以字长会返回 0 到字长 - 1 范围内的随机数;

Random indexGen = new Random();
int i = indexGen.nextInt(wordlength -1);
int j = indexGen.nextInt(wordlength -1 - i) + i;

另外,我阅读伪代码的方式是,您只想将 i 处的字符与 j 处的字符交换,这样您就可以执行此操作

char[] charArray = yourWord.toCharArray()
char temp = charArray[i];
charArray[i] = charArray[j];
charArray[j] = temp;
String finalWord = new String(charArray);

使用子字符串编辑

首先修复您的逻辑,以便您的索引始终正确并确保0 <= i < j <= wordlength. 将其放入 if 语句中,然后您将知道索引是否错误

if( 0 <= i && i < j && j <=wordlength)
{
     String first = word.substring(0, i);
     String middle = word.substring(i+1, j);
     String last = word.substring(j+1, wordLength);
     //... etc
}
else
     System.out.println("There was an indexing error: i = " + i + ", j = " + j);

编辑索引

int i = (int) ((Math.random() * wordLength) - 1)
if ( i < 0)
    i = 0;

然后 j 相同,但检查j > i. 另一种选择是Math.abs()像这样使用

int i = Math.abs((int) ((Math.random() * wordLength) - 1))
于 2013-10-13T23:05:44.143 回答
1
  i = (int) ((Math.random() * wordLength) - 1); 
  j = (int) (Math.random() * (wordLength - i)) + i; //  

在这两行中,有大小写(int) (Math.random() * (wordLength - i))会导致0and i == j。如果是这样,那么下面的代码行:

String middle = word.substring(i+1, j); 
          // if i==j, then  i+1 > j which will result in index exception.
  1. 用调试器一步一步彻底调试你的代码,找出BUG。
  2. 使用Random类,它有一个很好的函数random.nextInt(n)来返回一个介于 0(包括)和指定值(不包括)之间的随机整数。
于 2013-10-13T23:17:47.830 回答
0

在我看来,你的 i 和 j 可以是字符串大小之外的位置。尝试改变获得随机位置的方式。

试一试:

Random rand = new Random();
int i = rand.nextInt(wordLength - 1); // This will return you a random position between 0 and wordLength -2
int j = rand.nextInt(wordLength - i) + i; // This should give you a position after or equals i.
于 2013-10-13T23:08:39.810 回答
0

就像上面所说的 Sage 和 Java Devil 一样,第 18-19 行导致了您的问题,但是由于您使用Math.random()的是 ,因此很难在调试器中重现您的问题 - 您正在创建本质上不确定的东西。但是,由于您正在寻找随机,关键是要确保

  1. i>= 0,并且
  2. j> i(或i+1,取决于您想要的确切结果)。

这个练习似乎是在探索这个Math库,所以我建议研究它的一些其他方法,以确保它i始终j具有可接受的值(比如Math.min()Math.max())。

于 2013-10-13T23:24:46.637 回答
0

这就是解决方案。

import java.util.Scanner;

public class PermuteCharacters
{
   public static void main(String[] args)
 {
       Scanner in = new Scanner(System.in);

  System.out.println("Enter a word to permute: ");

  String word = in.next();
  for (int n = 0; n < word.length(); n++)
  {
     /** 
        The -1 here guarantees that later we won't pick a j that goes off
        the end of the string. This is important since since the 
        pseudocode tells us to pick a j > i
     */
     int i = (int) (Math.random() * word.length() - 1);
     int j = (int) (Math.random() * (word.length() - i - 1)) + i + 1;

     String first = word.substring(0, i);
     String middle = word.substring(i + 1, j);
     String last = word.substring(j + 1);

     word = first + word.charAt(j) + middle + word.charAt(i) + last;
  }

  System.out.println("Your permuted word is: " + word);
   }
}
于 2013-10-24T15:20:51.953 回答
0

这段代码对我有用:

import java.util.Random;

public class Word
{
   private Random generator = new Random();
   public Word() 
   {
        generator = new Random();
        final long SEED = 42;
        generator.setSeed(SEED);
   }

   public String scramble(String word)
   {     
    int lenWord = word.length();      
    for (int l = 0; l < lenWord; l++)
    {
        int i = generator.nextInt(lenWord - 1);    
        int j = i + 1 + generator.nextInt(lenWord - i - 1);

        String letterI = word.substring(i, i + 1);
        String letterJ = word.substring(j, j + 1);

        String FIRST = word.substring(0, i);
        String MIDDLE = word.substring(i + 1, j);;
        String LAST = word.substring(j + 1, lenWord);

        word = FIRST + letterJ + MIDDLE + letterI + LAST;
    }
    return word;
}
}
于 2016-07-03T14:56:48.890 回答