因此,要理解我正在尝试做什么,这个问题有点复杂。
基本上,我试图随机生成3个载体,大小均为11。
第一个向量在位置0必须为1,接下来的5个位置为0(例如100000),而接下来的5个数字可以是0 1或2,但在最后5位数中只能使用一个零,因此10000012101是有效的,但10000012001不会。
同样适用于第二个和第三个向量,但第一个将移动第二个和第三个的位置(第二个为010000xxxxx,第三个为001000xxxxx)。
还有更多条件需要满足。每个向量必须在至少5个位置上彼此不同(10000011210与50000个位置中的01000022100不同)。
但是,还有一个最终约束条件,指出如果添加模3的向量,那么添加这两个向量的结果必须在向量中至少有5个NON零值。
我通过使用arraylists来解决这个问题。我知道每个矢量的每个arraylist的前6个元素我手动将这些元素放入其中,对于接下来的5个元素,我随机分配这些元素,如果在最后5位数中有多个0,我会再次递归地调用该方法。
我对这个程序的问题是,当我尝试运行我的代码时,它会出现一个问题 线程“main”java.lang.StackOverflowError中的异常 在java.util.ArrayList.get(未知来源)
我认为这是因为它不断尝试循环并因此崩溃,但我不确定。请参阅下面的代码。
import java.util.ArrayList;
/**
* The purpose of this class is to be able to capture different ways
* of generating six vectors that will produce a collection of 729
* vectors that guarantee 9 out of 11 correct.
*/
public class GenerateVectors {
static ArrayList<Integer> firstVector = new ArrayList<Integer>();
static ArrayList<Integer> secondVector = new ArrayList<Integer>();
static ArrayList<Integer> thirdVector = new ArrayList<Integer>();
static ArrayList<Integer> sumOfXandY = new ArrayList<Integer>();
//Creates the first vectors to ensure it starts with "1,0,0,0,0,0"
//and has at most one more zero in the last 5 digits
public void createFirstVector(){
int[] fir stVector1 = {1,0,0,0,0,0};
for (int i=0; i<firstVector1.length; i++) {
firstVector.add(firstVector1[i]);
}
for(int i = 0; i < 5; i++){
int x = (int) (Math.random()*3);
firstVector.add(x);
}
int j = 0;
for(int i = 6; i<firstVector.size(); i++){
if(firstVector.get(i).equals(0)){
j++;
}
}
if(j>1){
OneZeroInLastFive(firstVector);
}
int[] sum = {0,0,0,0,0,0,0,0,0,0,0};
for (int i=0; i<sum.length; i++) {
sumOfXandY.add(sum[i]);
}
}
//Edits the vector if there is more than 0 in the last five digits
public void OneZeroInLastFive(ArrayList<Integer> x){
int j = 0;
for(int i = 6; i<x.size(); i++){
if(x.get(i).equals(0)){
j++;
}
}
if(j>1){
x.set(6, (int) (Math.random()*3));
x.set(7, (int) (Math.random()*3));
x.set(8, (int) (Math.random()*3));
x.set(9, (int) (Math.random()*3));
x.set(10, (int) (Math.random()*3));
j = 0;
OneZeroInLastFive(x);
}
}
//Creates the second vector with the last 5 digits random
public void createSecondVector(){
int[] secondVector1 = {0,1,0,0,0,0};
for (int i=0; i<secondVector1.length; i++) {
secondVector.add(secondVector1[i]);
}
for(int i = 0; i < 5; i++){
int x = (int) (Math.random()*3);
secondVector.add(x);
}
}
//Creates the third vector with the last 5 digits random
public void createThirdVector(){
int[] thirdVector1 = {0,0,1,0,0,0};
for (int i=0; i<thirdVector1.length; i++) {
thirdVector.add(thirdVector1[i]);
}
for(int i = 0; i < 5; i++){
int x = (int) (Math.random()*3);
thirdVector.add(x);
}
}
/**
* Will edit the second vector to ensure the following conditions are satisfied
* - The sum of x and y modulo 3 has at least 5 NON zeros
* - x and y must DIFFER in at least 5 places
* - There is only one zero within the last 5 digits
*
*/
public void checkVectors(ArrayList<Integer> x, ArrayList<Integer> y){
int k = 0;
int m = 0;
for(int j = 0; j < x.size(); j++){
if(x.get(j).equals(y.get(j))){
;
}
else{
k++;
}
}
for(int i = 6; i<y.size(); i++){
if(y.get(i).equals(0)){
m++;
}
}
if((k>4 && m<1)&& checkNonZeros(x,y)){
System.out.println("Conditions met");
}
else{
y.set(6, (int) (Math.random()*3));
y.set(7, (int) (Math.random()*3));
y.set(8, (int) (Math.random()*3));
y.set(9, (int) (Math.random()*3));
y.set(10, (int) (Math.random()*3));
k = 0;
m = 0;
checkVectors(x,y);
}
}
public ArrayList<Integer> addTwoVectors(ArrayList<Integer> x, ArrayList<Integer> y, ArrayList<Integer> z){
for(int i = 0; i<x.size(); i++){
int j = x.get(i);
int k = y.get(i);
z.set(i, ((j+k)%3));
}
return z;
}
public boolean checkNonZeros(ArrayList<Integer> x, ArrayList<Integer> y){
addTwoVectors(x,y, sumOfXandY);
int j = 0;
for(int i = 0; i<firstVector.size(); i++){
if(sumOfXandY.get(i).equals(0)){
;
}
else{
j++;
}
}
if(j<5){
return false;
}
else {
return true;
}
}
public static void main(String[] args){
GenerateVectors g = new GenerateVectors();
g.createFirstVector();
g.createSecondVector();
g.createThirdVector();
g.checkVectors(firstVector,secondVector);
g.checkVectors(secondVector,thirdVector);
System.out.println(firstVector);
System.out.println(secondVector);
System.out.println(thirdVector + "\n");
System.out.println(g.checkNonZeros(firstVector, secondVector));
System.out.println(g.checkNonZeros(secondVector,thirdVector));
System.out.println(sumOfXandY);
}
}
任何帮助都将非常感谢!!!
答案 0 :(得分:3)
问题在于你有方法以递归方式调用自己以便“重做”,这可能会在你获得成功之前多次发生。这对于像scheme或ml这样的语言很好,它们可以进行正确的尾递归,但是java没有,所以你得到堆栈溢出。
为了解决这个问题,您需要手动将递归代码转换为循环。代码如下:
method(arg1, arg2) {
Code_block_1;
if (test) {
Code_block_2;
} else {
Code_block_3;
method(newarg1, newarg2);
}
}
需要变得像:
method(arg1, arg2) {
Code_block_1;
while(!test) {
Code_block_3;
arg1 = newarg1;
arg2 = newarg2;
Code_block_1;
}
Code_block_2;
}
如果愿意,您可以重构内容以删除/合并重复的代码。