Construction of a class in java - java

I should carry out this exercise in the creation of a class, I uploaded this is the professor's solution, in sum and product methods can not quite figure out what place and why use "A".
class Vettore {
private int[] V = new int[6];
public Vettore(int[] X) {
if (X.length != 6)
throw new BadDataException();
for (int i = 0; i < 6; i++)
if (X[i] < 0)
throw new BadDataException();
else
V[i] = X[i];
}
public Vettore() {}
public Vettore somma(Vettore X) {
int[] A = new int[6];
for (int i = 0; i < 6; i++)
A[i] = V[i] + X.V[i];
return new Vettore(A);
}
public Vettore prodotto(Vettore X) {
int k = 0;
for (int i = 0; i < 6; i++)
k += V[i] * X.V[i];
return k;
}
public int get(int i) {
if (i < 0 || i > 5)
throw new BadDataException();
return V[i];
}
public String toString() {
String t = "( ";
for (int i = 0; i < 6; i++)
t += V[i] + (i == 5 ? " " : ", ");
return t + ")";
}
public boolean equals(Vettore X) {
for (int i = 0; i < 6; i++)
if (V[i] != X.V[i])
return false;
return true;
}
}

As far as I see it, and assuming somma means sum and prodotto means product, The A is needed because you have to store the sum values of the V and X.V arrays for every index. If you didn't use another array for this, you wouldn't be able to achive adding the appropriate indexes in somma for example. This method stands for - as I see it - Adding the two arrays' appropriate elements.
EDIT: another thing. Are you sure that the return types match variables to return? I elaborated the use of somma but didn't pay attention that prodotto has a wrong return type, just as it was said in the comments.

You might want to correct the prodotto method definition as -
public Vettore prodotto(Vettore X) {
int[] K = new int[6]; // deault values are 0
for (int i = 0; i < 6; i++)
K[i] += V[i] * X.V[i];
return new Vettore(K);
}
This would evaluate the product of the array field V for two instances of class Vettore namingly X the input param and the current instance that you would call the method from.
return new Vettore(K); creates a new instance of Vettore class with K as arrays field, while executing the constructor logic in place as follows -
public SumAndProductExercise(int[] X) {
if (X.length != 6) { // length of the array is 6 or not
throw new BadDataException();
}
for (int i = 0; i < 6; i++) {
if (X[i] < 0) { // all the elements of array are >=0 or not
throw new BadDataException();
} else {
V[i] = X[i]; // the field on the new instance
}
}
}

Related

Dynamic naming of variable (E1, E2, E3 ...)

I was wondering if there is a way or a library I can use to do the following:
I have an arraylist of objects where each obj has a name.
The list needs to always be unique with a maximum of 5 elements like [E1,E2,E3]
If for example the list has initial form [E3,E5] and I add an object, its name should be E1 and the list will be [E1,E3,E5] or [E3,E5,E1] it doesn't matter, as long as the name is unique and the item is added to the list starting from 1 to 5.
If add another item, it should be [E3,E5,E1,E2], always a unique name and between 1 and 5
These are my failed attempts,
StartNode node = new StartNode();
node.setName("E1");
for (int i = 0; i < circuit.getNbStartNodes(); i++) {
for (int j = 1; j <= circuit.getNbStartNodes(); j++) {
String test = ((StartNode) circuit.getStartNode(j)).getName();
if (("E"+j).equalsIgnoreCase(test) && ("E"+j).equalsIgnoreCase(node.getName()) ) {
break;
}
else
node.setName("E" + j);
}
}
/*while (t <= circuit.getNbStartNodes()) {
for (int j = 0; j < circuit.getNbStartNodes(); j++) {
String test = ((StartNode) circuit.getStartNode(j)).getName();
if (("E" + t).equalsIgnoreCase(test) || ("E" + t).equalsIgnoreCase(node.getName()))
break;
else {
node.setName("E" + t);
}
}
t++;
}
*/
/* for (int i = 1; i <= circuit.getNbStartNodes(); i++) {
for (int j = 0; j < circuit.getNbStartNodes(); j++) {
String test = ((StartNode) circuit.getStartNode(j)).getName();
if (!("E" + i).equalsIgnoreCase(test)) {
node.setName("E" + i);
t=0;
break;
}
}
if (t==0)
break;
else
continue;
*/
//String test = ((StartNode) circuit.getStartNode(i)).getName();
//for (int j = 1; j <= circuit.getNbStartNodes(); j++) {
// if (!("E" + j).equalsIgnoreCase(test))
// node.setName("E" + j);
//}
What did I do wrong in my code?
Create a small boolean array to track which names are already used and populate it with accordingly
Find the first unused element and use it as id.
boolean[] used = new boolean[circuit.getNbStartNodes()];
for (int i = 0; i < used.length; i++) {
int index = Integer.parseInt(((StartNode) circuit.getStartNode(j)).getName().substring(1)) - 1; // should be in range 0..4
used[index] = true;
}
String name = "E";
for (int i = 0; i < used.length; i++) {
if (!used[i]) {
name += String.valueOf(i + 1); // starting from 1
break;
}
}
System.out.println("free name: " + name);
StartNode node = new StartNode();
node.setName(name);
// add new node to circuit, etc.
With small values, Alex' solution works fine.
However, if you ever come across a use case where the number of elements become potentially large, then you could use a TreeSet to keep track of the unused numbers. Further, the nextCeilValue is the next number to pick when there are no removed numbers.
In the below code, I have created a UniqueNumber class, which is able to get the next number, or remove a given number. Note that this code provides integers starting from 0. Of course, you could easily convert this to your E-numbers using the function i -> "E" + (i + 1).
public class UniqueNumber {
private int nextCeilValue;
private final TreeSet<Integer> removedNumbers = new TreeSet<>(Integer::compare);
public int get() {
if (removedNumbers.isEmpty()) {
return nextCeilValue++;
}
else {
int number = removedNumbers.first();
removedNumbers.remove(number);
return number;
}
}
public boolean remove(int number) {
if (number < 0 || number > nextCeilValue) {
return false;
}
if (number == nextCeilValue) {
nextCeilValue--;
}
else {
removedNumbers.add(number);
}
return true;
}
public int size() {
return nextCeilValue - removedNumbers.size();
}
}
In order to test this, we first need to simulate your initial situation. In our integer-starting-from-zero-world, we need the numbers 2 and 4 (representing E3 and E5). In below code, we need to call get five times, and then remove element 0, 1 and 3. Of course, we could have created a UniqueNumber(int... initialValues) constructor which does this under the hood.
UniqueNumber un = new UniqueNumber();
for (int i = 0; i < 5; i++) {
un.get();
}
un.remove(0); // Remove E1
un.remove(1); // Remove E2
un.remove(3); // Remove E4
In order to get the next value, simply use this:
StartNode node = new StartNode();
node.setName("E" + (un.get() + 1));

Finding the smallest integer that appears at least k times

You are given an array A of integers and an integer k. Implement an algorithm that determines, in linear time, the smallest integer that appears at least k times in A.
I have been struggling with this problem for awhile, coding in Java, I need to use a HashTable to find the smallest integer that appears at least k times, it also must be in linear time.
This is what I attempted but it does not pass any of the tests
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
if (k <= table.get(arr[i])) {
ans = Math.min(ans, arr[i]);
}
}else{
table.put(arr[i], 1);
}
}
return ans;
}
Here is the empty code with all of the test cases:
import java.io.*;
import java.util.*;
public class Lab5
{
/**
* Problem 1: Find the smallest integer that appears at least k times.
*/
private static int problem1(int[] arr, int k)
{
// Implement me!
return 0;
}
/**
* Problem 2: Find two distinct indices i and j such that A[i] = A[j] and |i - j| <= k.
*/
private static int[] problem2(int[] arr, int k)
{
// Implement me!
int i = -1;
int j = -1;
return new int[] { i, j };
}
// ---------------------------------------------------------------------
// Do not change any of the code below!
private static final int LabNo = 5;
private static final String quarter = "Fall 2020";
private static final Random rng = new Random(123456);
private static boolean testProblem1(int[][] testCase)
{
int[] arr = testCase[0];
int k = testCase[1][0];
int answer = problem1(arr.clone(), k);
Arrays.sort(arr);
for (int i = 0, j = 0; i < arr.length; i = j)
{
for (; j < arr.length && arr[i] == arr[j]; j++) { }
if (j - i >= k)
{
return answer == arr[i];
}
}
return false; // Will never happen.
}
private static boolean testProblem2(int[][] testCase)
{
int[] arr = testCase[0];
int k = testCase[1][0];
int[] answer = problem2(arr.clone(), k);
if (answer == null || answer.length != 2)
{
return false;
}
Arrays.sort(answer);
// Check answer
int i = answer[0];
int j = answer[1];
return i != j
&& j - i <= k
&& i >= 0
&& j < arr.length
&& arr[i] == arr[j];
}
public static void main(String args[])
{
System.out.println("CS 302 -- " + quarter + " -- Lab " + LabNo);
testProblems(1);
testProblems(2);
}
private static void testProblems(int prob)
{
int noOfLines = prob == 1 ? 100000 : 500000;
System.out.println("-- -- -- -- --");
System.out.println(noOfLines + " test cases for problem " + prob + ".");
boolean passedAll = true;
for (int i = 1; i <= noOfLines; i++)
{
int[][] testCase = null;
boolean passed = false;
boolean exce = false;
try
{
switch (prob)
{
case 1:
testCase = createProblem1(i);
passed = testProblem1(testCase);
break;
case 2:
testCase = createProblem2(i);
passed = testProblem2(testCase);
break;
}
}
catch (Exception ex)
{
passed = false;
exce = true;
}
if (!passed)
{
System.out.println("Test " + i + " failed!" + (exce ? " (Exception)" : ""));
passedAll = false;
break;
}
}
if (passedAll)
{
System.out.println("All test passed.");
}
}
private static int[][] createProblem1(int testNo)
{
int size = rng.nextInt(Math.min(1000, testNo)) + 5;
int[] numbers = getRandomNumbers(size, size);
Arrays.sort(numbers);
int maxK = 0;
for (int i = 0, j = 0; i < size; i = j)
{
for (; j < size && numbers[i] == numbers[j]; j++) { }
maxK = Math.max(maxK, j - i);
}
int k = rng.nextInt(maxK) + 1;
shuffle(numbers);
return new int[][] { numbers, new int[] { k } };
}
private static int[][] createProblem2(int testNo)
{
int size = rng.nextInt(Math.min(1000, testNo)) + 5;
int[] numbers = getRandomNumbers(size, size);
int i = rng.nextInt(size);
int j = rng.nextInt(size - 1);
if (i <= j) j++;
numbers[i] = numbers[j];
return new int[][] { numbers, new int[] { Math.abs(i - j) } };
}
private static void shuffle(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++)
{
int rndInd = rng.nextInt(arr.length - i) + i;
int tmp = arr[i];
arr[i] = arr[rndInd];
arr[rndInd] = tmp;
}
}
private static int[] getRandomNumbers(int range, int size)
{
int numbers[] = new int[size];
for (int i = 0; i < size; i++)
{
numbers[i] = rng.nextInt(2 * range) - range;
}
return numbers;
}
}
private static int problem1(int[] arr, int k) {
// Implement me!
Map<Integer, Integer> table = new TreeMap<Integer, Integer>();
for (int i = 0; i < arr.length; i++) {
if (table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
} else {
table.put(arr[i], 1);
}
}
for (Map.Entry<Integer,Integer> entry : table.entrySet()) {
//As treemap is sorted, we return the first key with value >=k.
if(entry.getValue()>=k)
return entry.getKey();
}
//Not found
return -1;
}
As others have pointed out, there are a few mistakes. First, the line where you initialize ans,
int ans = 0;
You should initialize ans to Integer.MAX_VALUE so that when you find an integer that appears at least k times for the first time that ans gets set to that integer appropriately. Second, in your for loop, there's no reason to skip the first element while iterating the array so i should be initialized to 0 instead of 1. Also, in that same line, you want to iterate through the entire array, and in your loop's condition right now you have i < k when k is not the length of the array. The length of the array is denoted by arr.length so the condition should instead be i < arr.length. Third, in this line,
if (k < table.get(arr[i])){
where you are trying to check if an integer has occurred at least k times in the array so far while iterating through the array, the < operator should be changed to <= since the keyword here is at least k times, not "more than k times". Fourth, k should never change so you can get rid of this line of code,
k = table.get(arr[i]);
After applying all of those changes, your function should look like this:
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
if (k <= table.get(arr[i])) {
ans = Math.min(ans, arr[i]);
}
}else{
table.put(arr[i], 1);
}
}
return ans;
}
Pseudo code:
collect frequencies of each number in a Map<Integer, Integer> (number and its count)
set least to a large value
iterate over entries
ignore entry if its value is less than k
if entry key is less than current least, store it as least
return least
One line implementation:
private static int problem1(int[] arr, int k) {
return Arrays.stream(arr).boxed()
.collect(groupingBy(identity(), counting()))
.entrySet().stream()
.filter(entry -> entry.getValue() >= k)
.map(Map.Entry::getKey)
.reduce(MAX_VALUE, Math::min);
}
This was able to pass all the cases! Thank you to everyone who helped!!
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
}else{
table.put(arr[i], 1);
}
}
Set<Integer> keys = table.keySet();
for(int i : keys){
if(table.get(i) >= k){
ans = Math.min(ans,i);
}
}
if(ans != Integer.MAX_VALUE){
return ans;
}else{
return 0;
}
}

Return statement cannot find the local variable inside the method

I am a 2nd year CS student and trying to fix a simple method. The logic is fairly easy but somehow I still get an error although I don't know what's wrong here.
The problem :
The beginning of the class:
private Integer dt[];
private int size;
IntManager(int k){
dt = new Integer[k];
size = 0;
}
The method inside the class:
public Integer max(){
//return largest value in dt; null if size == 0
if (size == 0) return null;
else{
Integer biggest = dt[0];//trouble here; changing to int won't help & var name also
for (int j = 0; j < size ; j++) {
if (dt[j] < biggest) biggest = dt[j];
}
}
return biggest;
}
Main class:
IntManager num = new IntManager(100);
for (int j = 0; j < 20 ; j++) {
int x = (int)(Math.random()*10);
num.add(x);
}
num.add(57);
System.out.println(num);
System.out.println(num.found(5));//Ignore this
System.out.println(num.max());
Your biggest variable is defined inside the ifelse scope therefore is not visible outside of that segment
declare the Integer as a hole method variable...
Example:
public Integer max(){
Integer biggest=null;
if (size != 0) {
Integer biggest = dt[0];
for (int j = 0; j < size ; j++) {
if (dt[j] < biggest) biggest = dt[j];
}
}
return biggest;
}
The problem is with your blocks
public Integer max(){
//return largest value in dt; null if size == 0
if (size == 0) return null;
else{
Integer biggest = dt[0];//trouble here; changing to int won't help & var name also
for (int j = 0; j < size ; j++) {
if (dt[j] < biggest) biggest = dt[j];
}
}
return biggest;
}
You're declaring biggest within the scope of that else block, so it is not visible when you reach your return statement. To correct it you should have something like:
public Integer max(){
//return largest value in dt; null if size == 0
Integer biggest = dt[0]
if (size == 0) return null;
else{
;//trouble here; changing to int won't help & var name also
for (int j = 0; j < size ; j++) {
if (dt[j] < biggest) biggest = dt[j];
}
}
return biggest;
}

Null Pointer Exception Error in a DoubleMatrix class [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 7 years ago.
I'm having trouble with a java problem. I get this error:
Exception in thread "main" java.lang.NullPointerException
at DoubleMatrix.getDim1Size(DoubleMatrix.java:28)
at Program3.main(Program3.java:16)
I don't understand where it is null
public class DoubleMatrix
{
private double[][] doubMatrix;
public DoubleMatrix(int firstDim, int secondDim, double upperLimit)
{
if(firstDim > 0 && secondDim > 0 && upperLimit > 0){
firstDim = 1;
secondDim = 1;
upperLimit = 1;
}
}
public DoubleMatrix(double[][] tempArray)
{
if(tempArray != null && tempArray.length != 0){
for(int i =0; i < tempArray.length; i++) {
doubMatrix = tempArray;
}
}
else{
tempArray = new double[1][1];
}
}
public int getDim1Size(){
int firstDim1 = doubMatrix.length;
return firstDim1;
}
public int getDim2Size(){
int secondDim1 = doubMatrix[0].length;
return secondDim1;
}
private void makeDoubMatrix(int firstDim, int secondDim, double upperLimit){
double[][] randomMatrix = new double[firstDim][secondDim];
for(int row = 0; row < doubMatrix.length; row++) {
for(int column = 0; column < doubMatrix[row].length; column++){
doubMatrix[row][column] = (double)(Math.random() * 100);
}
}
}
public DoubleMatrix addMatrix(DoubleMatrix arrayObj)
{
if(doubMatrix.length == arrayObj.doubMatrix.length && doubMatrix[0].length == arrayObj.doubMatrix[0].length){
double[][] TotalTwoDimArray = new double[doubMatrix.length][doubMatrix[0].length];
for(int row = 0; row < TotalTwoDimArray.length; row++){
for(int column = 0; column < TotalTwoDimArray[row].length; column++){
TotalTwoDimArray[row][column] = doubMatrix[row][column] + arrayObj.doubMatrix[row][column];
}
}
return new DoubleMatrix(TotalTwoDimArray);
}
return new DoubleMatrix(1, 1, 1);
}
public DoubleMatrix getTransposedMatrix(){
double[][] TransMatrix = new double[doubMatrix[0].length][doubMatrix.length];
for(int row = 0; row < doubMatrix.length; row++){
for(int column = 0; column < doubMatrix[row].length; column++){
TransMatrix[row][column] = doubMatrix[column][row];
}
}
return new DoubleMatrix(TransMatrix);
}
public DoubleMatrix multiplyMatrix(DoubleMatrix obj1)
{
if(doubMatrix[0].length == obj1.doubMatrix.length){
double[][] multipliedMatrix = new double[doubMatrix.length][obj1.doubMatrix[0].length];
for(int i = 0; i < multipliedMatrix.length; i++){
for(int j = 0; j < multipliedMatrix[i].length; j++){
for(int k = 0; k < doubMatrix[0].length; k++){
multipliedMatrix[i][j] = doubMatrix[i][k] * obj1.doubMatrix[k][j] + multipliedMatrix[i][j];
}
}
}
return new DoubleMatrix(multipliedMatrix);
}
return new DoubleMatrix(1, 1, 1);
}
public void printMatrix(String titles){
System.out.println(titles);
for(int row = 0; row < doubMatrix.length; row++){
for(int column = 0; column < doubMatrix[row].length; column++){
System.out.printf("%9.1f", doubMatrix[row][column]);
}
System.out.println();
}
}
}
// main in different class
public class Program3
{
public static void main(String[] args)
{
DoubleMatrix doubMatObj1;
DoubleMatrix doubMatObj2;
DoubleMatrix doubMatObj3;
int max = 10;
int min = 3;
int firstDim = (int)(Math.random() * (max - min + 1) + min);
int secondDim = (int)(Math.random() * (max - min + 1) + min);
doubMatObj1 = new DoubleMatrix(firstDim, secondDim, 100.);
doubMatObj2 = new DoubleMatrix(doubMatObj1.getDim1Size(), doubMatObj1.getDim2Size(), 100.);
doubMatObj3 = doubMatObj1.addMatrix(doubMatObj2);
doubMatObj1.printMatrix("First Matrix Object");
doubMatObj2.printMatrix("Second Matrix Object");
doubMatObj3.printMatrix("Result of Adding Matrix Objects");
doubMatObj2.printMatrix("Result of Transposing Matrix Object");
doubMatObj1.multiplyMatrix(doubMatObj2);
doubMatObj3.printMatrix("Result of Multiplying Matrix Objects");
}
}
In java, non primitives don't get initialized by just declaring them. So if you get a NullPointerException in a line like foo.bar(), you know that foo had to be null. In your case you have doubMatrix.length, which indicates that doubMatrix has never been initialized. Looking at your code, only the second constructor ever initializes that variable, so calling the first constructor will leave doubMatrix==null to always be true.
I hope that is enough info to help you fix your problem yourself (and similar problems in the future), but I am not going to post a working code example, since fixing your code yourself will be a good exercise!
On a sidenote, in your second constructor you have:
for(int i =0; i < tempArray.length; i++) {
doubMatrix = tempArray;
}
If tempArray.length is for example 5, you would assign the same value 5 times to the same variable. I don't know what you are trying to do there, but it is certainly not what you had in mind.

Merging two ArrayLists of type String in Java

I have two ArrayLists of String type and want to mix them as follows:
SPK = [A,A,A,B,A,A,A,A,A,B] and
DA= [ofm,sd,sd,sd,sd,sd,sd,sd,sd,sv]
I need to create some String in other ArrayList as below:
SPK_DA = [ofmAsdAsdAB, sdBA, sdAsdAsdAsdAsdAB]
in this set I need to equate previous similar elements before turning (from A to B) occur in SPK array.
I wrote a program but it adds one extra sdA (I don't know why I can't do such a simple thing).
for (int i=0; i <SPK.size()-1; i++){
if (SPK.get(i)==SPK.get(i+1) && (i+1)<= SPK.size()){
speakerChain = DA.get(i)+SPK.get(i);
speakerChain1=DA.get(i+1)+SPK.get(i+1);
SPKTrace.add(speakerChain);
SPKTrace.add(speakerChain1);
}else if (SPK.get(i)!=SPK.get(i+1)){
if (SPKTrace.size()!=0){
SPKTrace.add(SPK.get(i+1));
//SPKString = removeDuplicates (SPKTrace);
String S1 = arrayTostring(SPKTrace);
SPKResource.add(S1);
SPKTrace.clear();
}else {
SPKTrace.add(DA.get(i)+SPK.get(i)+SPK.get(i+1));
//SPKString = removeDuplicates (SPKTrace);
String S1 = arrayTostring(SPKTrace);
SPKResource.add(S1);
SPKTrace.clear();
}
}
}
}
}
System.out.println(SPKResource.toString());
My Output: [ofmAsdAsdAsdAB, sdBA, sdAsdAsdAsdAsdAsdAsdAsdAB]
When I use for loop it happens that it creates more sdAs....
Indicies.add(0);
for (int i = 0; i < SPK.size() - 1; i++) {
if (SPK.get(i) != SPK.get(i + 1)) {
Indicies.add(i + 1);
}
}
for (int i = 0; i < Indicies.size() - 1; i++) {
Count.add(Indicies.get(i + 1) - Indicies.get(i));
}
Count.add((SPK.size() - Indicies.get(Indicies.size() - 1)));
System.out.println("count:" + Count);
int counter = 0;
int newIndex =0;
for (int j = 1; j <= Count.size(); j++) {
String element = "";
for (int kk = 0; kk < (Count.get(j-1)); kk++) {
element = element + (DA.get(kk+newIndex) + SPK.get(kk+newIndex));
}
newIndex = newIndex+Count.get(j-1);
if (element.endsWith("A")){
SPKResource.add(element+"B");
} else if (element.endsWith("B")){
SPKResource.add(element+"A");
}
}
}
}
for (String S:SPKResource){
System.out.println(SPKResource);
}
The above code can give me the answer but I think it is quite inefficient. Is there any idea to make it more efficient?

Categories

Resources