我正在创建一个程序,我将导入.dat文件并在命令提示符下打印这些值以便读取它。没有问题。唯一的问题是我无法弄清楚只打印某些变量的代码。
import java.io.*;
import java.util.Scanner;
public class program4
{
public static void main(String [] args) throws IOException
{
double [] values; //creating array called values
values = new double [40]; //establishing array that has 40 cells
int k; //creating counter integer
Scanner InputFile = new Scanner( new FileReader("temp.dat"));
k = 0;
while (InputFile.hasNextDouble()) //read values from file using ascending while loop
{
values[k] = InputFile.nextDouble();
k++;
}
for (k = 0 ; k < values.length ; k++)
System.out.println(values[k]);
InputFile.close();
}
}
初始化代码以摆脱.dat文件包含的重复项的最佳位置在哪里?
答案 0 :(得分:0)
创建一个方法,检查数组中是否存在多次值
boolean isDuplicate(double x, double[] array, int checkUpTo){
numOfOccurencies = 0;
for(int i = 0; i <= checkUpTo; i++)
if(x == array[i])
numOfOccurencies++;
return(numOfOccurencies > 1)? true : false;
}
然后
for (k = 0 ; k < values.length ; k++)
if(!isDuplicate(values[k], values, k)
System.out.println(values[k]);
因此,每次尝试从数组中打印双精度数时,如果双精度数出现多次,则检查该索引。这样你保证比你至少打印一次所有。例如,如果您在索引2和索引4处出现值,则首先在索引2处检查,因为您检查该索引,该值不重复并打印。之后,您最多检查4并找到第二次出现,因此不打印该值。
希望这有帮助
编辑:我假设您只想在打印时删除重复项。如果您不想存储重复值,则需要类似的内容:
boolean isDuplicate(double x, double[] array){
for(int i = 0; i < array.length; i++)
if array[i] == x
return true;
return false;
}
while (InputFile.hasNextDouble()) //read values from file using ascending while loop
{
double temp = InputFile.nextDouble();
if(!isDuplicate(temp, values){
values[k] = temp
k++;
}
}
for (k = 0 ; k < values.length ; k++)
System.out.println(values[k]);
答案 1 :(得分:0)
对程序的最简单修改是通过检查已存储的值来修改while循环以不存储重复项:
while (InputFile.hasNextDouble()) //read values from file using ascending while loop
{
double nextValue = InputFile.nextDouble();
// check to see if next value has already been stored
boolean duplicate = false;
for (int i=0; i<k; i++) {
if (nextValue == values[i]) {
duplicate = true;
break;
}
}
// only store values if they have not already been read
if (!duplicate) {
values[k] = nextValue;
k++;
}
}
您可能还想修改print语句,以便仅将数组打印到您已写入值的索引(k
):
for (int i = 0 ; i < k ; i++) {
System.out.println(values[i]);
}
答案 2 :(得分:0)
一种方法是在构建数组后对其进行排序,并检查它是否具有重复值。
当然,每次添加项目时都可以强制它并循环整个数组,但这非常低效。下面的解决方案开始时效率也同样低,但也有优化的机会。
我故意避免提供代码,因为我认为你想要学习而不仅仅是复制粘贴。
一旦填充了数组values
(因此,在while
循环之后),对数组进行排序。您可能已经知道如何从以前的练习中对数组进行排序,但如果不这样做,bubble sort是最容易学习的(性能最差)。
有关简单的冒泡排序实现,请参阅this answer。
function bubbleSort:
//values is your array
//length is the length of values
loop i from 0 to length - 1
loop j from i+1 to length - 1
if values[i] > values[j]
swap values[i] and values[j]
end if
end loop
end loop
end function
一旦有了排序数组,循环遍历它并检查当前元素是否与前一个元素相同。如果是,那就是重复。
function removeDuplicates:
//values is your array
//non_duplicate_array is another array with only non duplicate values
loop from 1 to size-1 //and not from 0, because we are comparing
//an element with the previous and
//the element at 0 does not have a previous element
if values[i] == values[i-1]
//duplicate!
else
add element to non_duplicate_array.
end if
end loop
所以我们有:
您可以构建的一个优化是确保排序本身具有重复消除:
这是上面冒泡排序中最里面的循环:
loop j from i+1 to length - 1
if values[i] > values[j]
swap values[i] and values[j]
end if
end loop
此处,您可以将值添加到另一个数组,而不是交换值,同时只执行非重复项:
function bubbleSort:
//values is your array
//length is the length of values
//non_duplicate_array is another array that will eventually have
//sorted non duplicate values
loop i from 0 to length - 1
loop j from i+1 to length - 1
if values[i] != values[j]
if values[i] > values[j]
add values[j] to non_duplicate_array
else
add values[i] to non_duplicate_array
end if
end if
end loop
end loop
end function
排序是冒泡排序,所以它非常inefficient,特别是因为嵌套循环。但您可以使用merge sort或far more efficient的快速排序替换它。您可以调整合并或快速排序算法,以便删除重复项。
仅当您对输出数组进行排序时才有效。否则你需要强制它,就像@ xgeorgekx的回答一样。或者使用Set
。
编辑:
为了让您了解为什么会看到很多针对集合的建议,以下是Set
所需的全部内容:
Set valueSet = new HashSet<Double>();
...
...
while (InputFile.hasNextDouble())
{
valueSet.add(InputFile.nextDouble());
}
就是这样。该集合仅具有非重复值。但是你不会学习编程:-)。