multidimensional array with no repeated numbers of the same row - java

int matrice2 [][] = new int [5][5];
for (int i=0;i<5;i++) {
System.out.println(" ");
for(int j=0;j<5;j++) {
matrice2[i][j] = (int)(Math.random()*10);
System.out.print(" "+matrice2[i][j]+" ");
}
}
System.out.println(" ");
System.out.println(" ");
for (int i=0;i<5;i++) {
System.out.println(" ");
for(int j=0;j<5;j++) {
for (int k=0;k<5;k++) {
if(j!=k) {
if (matrice2[i][j]==matrice2[i][k]) {
matrice2[i][k]=(int)(Math.random()*10);
}
}
}
System.out.print(" "+matrice2[i][j]+" ");
}
}
I wanted to make a multidimensional array without having any repeated numbers in the same row so the column doesn't matter if it has repeating numbers.
What I did here is generate 5x5 arrays formed in square.
Having index "j" as the one that gets compared with numbers in index "k" that checks the whole row if there are numbers that is equal to the number it contains in index "j".
So my only problem is that after detecting the number in "k" that is equal to the number in "j", the number in index "k" will generate a new number replacing the current number in "k" but the result in console shows that the original 5x5 array which is the first formed of the array before it gets changed has been changed but the numbers that have been replaced generated a numbers that already exist even it should keep changing until "k" cannot detect any repeated numbers.
I can think of other ways of doing it but I really want to know why it doesn't work even though I really think that it shouldn't give any problems but I might have missed something.
here's the example of the results that shouldn't have occured.
from
9 1 3 8 4
5 3 2 4 8
9 8 5 6 5
6 3 0 8 7
2 8 6 3 9
to
9 1 3 8 4
5 3 2 4 8
9 8 5 6 9
6 3 0 8 7
2 8 6 3 9
it shouldn't happen because "k" should have seen it since he starts from index 0 to 4.
while "j" is in index 4 and "k" is in index 0 it should have detected it immediately and change the number in "k" to something else random.
EDIT: I see the different ways you guys are showing but what Im asking is to provide maybe a better solution without using any imports. our teacher gave us this assignment telling us without using any of those imports which makes it more complicated but it's what we are asked for.
I tried it with while but still no changes happening.

I editted your code in a different way. I wrote some comment to code understand clearly. Try it please.
public class UniqueMatrix {
public static void main(String[] args) {
int matrix[][] = new int[5][5];
boolean uniqeMatrixFound = false;
while (!uniqeMatrixFound) {
//fill matrix until uniqe matrix found value is true
fillMatrix(matrix);
for (int i = 0; i < matrix.length; i++) {
HashSet<Integer> columnNumber = new HashSet<>();
for (int j = 0; j < matrix.length; j++) {
columnNumber.add(matrix[j][i]);
}
//if set size not equal to matrix size , create an new uniqe matrix with breaking false value
if (columnNumber.size() != matrix.length) {
uniqeMatrixFound = false;
break;
}
uniqeMatrixFound = true;
}
}
//print an array
for (int i = 0; i < matrix.length; i++) {
System.out.println(" ");
for (int j = 0; j < matrix.length; j++) {
System.out.print(" " + matrix[i][j] + " ");
}
}
}
//create a matrix with unique value in all rows.
private static void fillMatrix(int[][] matrice2) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
for (int i = 0; i < matrice2.length; i++) {
Collections.shuffle(list);
for (int j = 0; j < matrice2.length; j++) {
matrice2[i][j] = list.get(j);
}
}
}
}

Here is your code edited. I also commented inline what were the changes and why. You could have done it more easy but I think it suites you more to edit your example so you can understand. Only issue is that you should have stored the value on matrice2[i][j] = newValue (to let k go to the end of the line and check with all other values that your random is not an existing number)
Hope it helps.
public class UniqueMatrix {
public static void main (String[] args) {
int matrice2 [][] = new int [5][5];
for (int i=0;i<5;i++) {
System.out.println(" ");
for(int j=0;j<5;j++) {
matrice2[i][j] = (int)(Math.random()*10);
System.out.print(" "+matrice2[i][j]+" ");
}
}
System.out.println(" ");
System.out.println(" ");
for (int i=0;i<5;i++) {
System.out.println(" ");
for(int j=0;j<5;j++) {
for (int k=0;k<5;k++) {
if(j!=k) {
if (matrice2[i][j]==matrice2[i][k]) {
int newValue = (int)(Math.random()*10);
//store the newly found value in j for you have time to check with others till the end
matrice2[i][j] = newValue;
}
}
}
System.out.print(" "+matrice2[i][j]+" ");
}
}
}
}

Here is a different approach to the problem that uses a shuffled ArrayList instead of checking whether a value exists in the current row or not.
int matrice2[][] = new int[5][5];
ArrayList<Integer> sourceMatrix = new ArrayList<Integer>();
for (int i = 0; i < 10; i++)
sourceMatrix.add(i);
//generate random matrix using shuffled arraylist
for (int i = 0; i < matrice2.length; i++) {
Collections.shuffle(sourceMatrix);
for (int j = 0; j < matrice2[i].length; j++) {
matrice2[i][j] = sourceMatrix.get(j);
}
}
//print generated matrix
for (int i = 0; i < matrice2.length; i++) {
for (int j = 0; j < matrice2[i].length; j++) {
System.out.print(matrice2[i][j]);
}
System.out.println();
}

The way I read your logic is that when you find a duplicate you generate a new number and that new number will validated in the next iteration of the outer (j) loop. The problem is when j==k because that number will not be validated, normally this isn't a problem since j will increase and then that number will be validated with the exception of when j==4 since that is the last iteration.
So modify the rightmost column and that value will not be checked because 'j==k' will never be false.

The problem in your code was that after you detected the duplicate value, you assigned the new generated random number without checking if it is also a duplicate number. what i did here is that i detect duplicate and before assigning/replacing the new generated random number i will check whether it is also duplicate or not, if it is duplicate i will generate another otherwise i will assign it and move on.
(int)(Math.random()*10); // this code does not guarantee that new unique number is generated every time you call it.
the problem is in the code below , you are updating matrice2[i][k] with new (int)(Math.random()*10) with out checking whether it is same or different number.
if (matrice2[i][j]==matrice2[i][k]) {
matrice2[i][k]=(int)(Math.random()*10);
}

Related

Trying to count repeated items in an integer Array but getting weird results

public static void checkMultiple(int a[]){
//will use this count variable later
//int[] count = new int[10];
//first scan over the array
for (int i = 0; i < a.length; i++)
{
//seeded loop to check against 1st loop
for (int j = 0; j < i; j++)
{
if (a[i] == a[j])
{
System.out.print(a[i] + " ");
}
}
}
}
I'm having trouble counting repeated numbers in an integer array of 10 random numbers. I havent wrote the "count" function yet but the checkMultiple() will print out the numbers that are repeated. However, some of the time it prints correctly such as:
4 2 9 0 9 6 3 3 7 5
9 3
the first line being the whole array and the second the numbers that are repeated at least once in the array. But when there is more than two of a single integer, it counts every single one of that integer such as:
9 5 2 8 5 5 7 6 3 3
5 5 5 3
Any tips or advice would be much appreciated!
It looks like as you are looping through and then immediately outputting the results.
This prevents the program from comparing what's being currently parsed and what has already been been parsed and counted.
I would pass an empty array into the first FOR loop and instead of "System.out.print," store the number in the passed-in array. You can then compare the values that have already been parsed against the value currently being parsed to see if it has already been counted.
When the outside FOR loop exits, output the array that was originally passed in empty (and now has a record of every duplicate in the initial array)
You are counting the number of duplicate instances. Your second example has three pairs of duplicate 5's. That's why you see the 5 repeated three times. Only output unique duplicate results.
Just use a hash map, if the key does not exist add it to the map with the value 1, if it does increase the value, then print the hash map.
A single iteration of the array will solve the problem.
Map<Integer, Integer> counter = new HashMap<>();
for (int i = 0; i < a.length; i++) {
if (counter.containsKey(a[i])) {
counter.put(a[i], counter.get(a[i]) + 1);
} else {
counter.put(a[i], 1);
}
}
Iterator it = counter.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next();
for (int i = 0; i < pair.getValue(); ++i) {
System.out.print(pair.getKey() + " ");
}
// or you could just print the number and how many times it was found
System.out.println(pair.getKey() + " " + pair.getValue());
it.remove();
}
try this
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Scanner;
public class BirthdayCake {
private static void printcake(int n,int[] arr){
//Map<Integer,Integer> ha = new HashMap<Integer,Integer>();
int temp = arr[0],max=0, count=0;
/*for(int i=1;i<n;i++){
max = arr[i];
if(max<=temp){
temp=max;
count++;
break;
}
else{
max = arr[i];
count++;
break;
}
}*/
Arrays.sort(arr);
for(int i:arr){
System.out.println(i);
}
System.out.println("max:" +max);
max = arr[arr.length-1];
for(int i=0;i<n;i++){
if(arr[i]==max){
count++;
}
}
System.out.println("count:" +count);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("Entere thye array size:");
int n = sc.nextInt();
int[] arr = new int[n];
for(int i=0;i<n;i++){
arr[i] = sc.nextInt();
}
printcake(n,arr);
}
}

Generation of 4 non repeating random numbers using arrays in java

I have this array
int [] marc = new int[4];
i need to insert a set of non repeating random numbers in the range of 1-10 to it
i'm using this for loop to set random numbers
for (he = 0; he < 4; he++) {
marc[he] = rn.nextInt(10 - 1 + 1) + 1;
marc[he]++;
}
it gives me random numbers but repeated ones inside the array
i'm also using
java.util.Random;
Well, yes, numbers can be repeated while being random. You need to do your own logic to validate if they're already on the array, this can be done with the following code:
In the code I used an array of 10 elements to observe there aren't repeated numbers even on that situation.
import java.util.Random;
public class RandomNumbersNoRepeating {
public static void main(String[] args) {
int array[] = new int[10];
Random random = new Random();
//Fills the array
for (int i = 0; i < array.length; i++) {
boolean found = false;
int r = 0;
do {
found = false;
r = random.nextInt(10) + 1;
//Here we check if the number is not on the array yet
for (int j = 0; j < array.length; j++) {
if (array[j] == r) {
found = true;
break;
}
}
} while (found);
array[i] = r;
}
//Prints the array
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
Another possible solution, as given in a comment could be to shuffle an array from 1-10, and get the first four numbers
Using java.util.Random; will generate repetitive numbers more often when your range is small, which in your case is only 10. There is no condition in your code that checks whether the generated random number already exists in your array or not.
Before inserting a generated number in to the array, you first need to check whether that number already exists in your array. If it does not, you insert that number in the array, otherwise you generate a next random number.

Negative Arrays and Error Messages

//MY TASK IS TWO MERGE TO ARRAYS INTO ASCENDING ORDER.Your program will accept each array as input from the keyboard. You do not know ahead of time how many values will be entered, but you can assume each array will have a maximum length of 10,000 elements. To stop entering values enter zero or a negative number. You should disregard any non-positive numbers input and not store these in the array.
The elements of the two input arrays should be in increasing order. In other words, each array element must have a value that is greater than or equal to the previous element value. An array may contain repeated elements.
import java.util.Scanner;
import java.lang.Math;
class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int one[]= new int[10000];
int two[]= new int[10000];
int lengthShort=0;
int lengthLong=0;
int a =0;
int b =0;
System.out.println("Enter the values for the first array, "
+ "up to 10000 values, enter a negative number to quit");
for(int i=0; i<one.length && scan.hasNext(); i++){
one[i] = scan.nextInt();
a++;
if(one[i]<0){
one[i]=0;
break;
}
}
int length1 = a-1;
System.out.println("Enter the values for the second array, "
+ "up to 10000 values, enter a negative number to quit");
for(int i=0; i<two.length && scan.hasNext(); i++){
two[i] = scan.nextInt();
b++;
if(two[i]<0){
two[i]=0;
break;
}
}
int lengthTwo = b-1;
int mergeOne[] = new int[length1];
for (int i = 0; i<mergeOne.length; i++){
mergeOne[i]=one[i];
}
int mergeTwo[] = new int[lengthTwo];
for (int i = 0; i<mergeTwo.length; i++){
mergeTwo[i]=two[i];
}
System.out.println("First Array:");
for(int i=0; i<mergeOne.length; i++){
System.out.print(mergeOne[i] + " ");
}
System.out.println("\nSecond Array:");
for(int i=0; i<mergeTwo.length; i++){
System.out.print(mergeTwo[i] + " ");
}
if(mergeOne.length<=mergeTwo.length){
lengthLong = mergeTwo.length;
lengthShort = mergeOne.length;
}
else if(mergeOne.length>=mergeTwo.length){
lengthShort = mergeTwo.length;
lengthLong = mergeOne.length;
}
int merged[] = new int[length1 + lengthTwo];
for(int i = 0; i<lengthShort; i++){
if(i==0){
if(mergeOne[i]<=mergeTwo[i]){
merged[i] = mergeOne[i];
merged[i+1] = mergeTwo[i];
}
else if(mergeTwo[i]<=mergeOne[i]){
merged[i] = mergeTwo[i];
merged[i+1]= mergeOne[i];
}
}
else if(i>0){
if(mergeOne[i]<=mergeTwo[i]){
merged[i+i] = mergeOne[i];
merged[i+i+1] = mergeTwo[i];
}
else if(mergeTwo[i]<=mergeOne[i]){
merged[i+i] = mergeTwo[i];
merged[i+i+1]= mergeOne[i];
}
}
}
if(mergeOne.length<mergeTwo.length){
for(int k=lengthShort; k<lengthLong; k++){
merged[k]=mergeTwo[k];
}
}
if(mergeOne.length>mergeTwo.length){
for(int k=lengthShort; k<lengthLong; k++){
merged[k]=mergeOne[k];
}
}
for(int i = 0; i<merged.length; i++){
if((i+1)==merged.length)
break;
if(merged[i]>merged[i+1]){
int temp = merged[i+1];
merged[i+1]=merged[i];
merged[i]= temp;
}
}
System.out.println("\nMerged array in order is: ");
for(int i = 0; i<merged.length; i++){
System.out.print(merged[i] + " ");
}
}
}
//My code compiles in drjava but I have two issues:
1) It doesn't order the numbers in ascending order
2) When I run it through the site I have to submit this on it gives me the message as follows:
Runtime Error
Exception in thread "main" java.lang.NegativeArraySizeException
at Main.main(Main.java:281)
at Ideone.assertRegex(Main.java:94)
at Ideone.test(Main.java:42)
at Ideone.main(Main.java:29)
You'll need to rethink your merge algorithm. Suppose you input arrays are
1 5 10 50 100 500
2 4 6 8 10 12 14 16
You'll need to repeatedly decide which element is smaller to put into the output. So after selecting N elements, your output will look like
1 2 4 5 6 8 10 10 12 14
And you will need to have indexes pointing at the place in the input arrays you'll need to look at next:
1 5 10 50 100 500
^^
2 4 6 8 10 12 14 16
^^
As you can see, the indexes could be at very different places in the input arrays. However, your code does a lot of this:
if(mergeOne[i]<=mergeTwo[i]){
which means it's only comparing elements from the input that are in the same location. This doesn't work, and trying to swap elements in the output after the fact isn't good enough to get the job done.
Basically, instead of having one index and comparing the elements of the two input arrays at the same index, you'll need two indexes. I'll let you take it from there, but I think you can figure it out.
(And I have no idea why you're getting NegativeArraySizeException.)

Unable to get a sorted array in ascending manner

I created a Java program that takes the user's choice and creates an int array of that size. Then the array is sorted and displayed and a number is asked to search in the array. I'm trying to use the bubble sort technique, however, the result always turns out to be a descending array rather than an ascending one.
import java.util.*;
class mt {
int i,M=0;
public void main() {
Scanner sc=new Scanner(System.in);
System.out.println("enter the size of array");
int sizeOfArray=sc.nextInt();
int arr[]= new int [sizeOfArray];
int temp;
System.out.println("enter the numbers");
for (i=0; i<sizeOfArray; i++) {
arr[i]=sc.nextInt();
}
System.out.println("the sorted array is below :");
for ( i=0; i<sizeOfArray-1; i++){
for (int j=0; j<sizeOfArray-2; j++) {
if (arr[j]>arr[j+1]) {
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
for (i=0; i<sizeOfArray; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
System.out.println("enter number to search");
int srch=sc.nextInt();
for (i=0; i<sizeOfArray; i++) {
if (arr[i]==srch)
{
System.out.println("found at "+i);
M++;
break;
}
else if (M==0&&i==sizeOfArray-1)
{
System.out.println("number not found");
}
}
}
}
Change your loops and condition as below
for ( i=0; i<arr.length - 1; i++){
for (int j=i+1; j<arr.length; j++) {
if (arr[i]>arr[j]) {
temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
So you get resulting array in ascending order. In your case, you are missing elements as you are iterating over from 0 - array.length - 2.
Firstly the code mentioned above had lot of silly mistakes which need to be corrected:
1. "String args[]" need to be added in the main() method.
2. For all the for loops where "i" is the variable, it need to be defined as an "int".
3. the variable "M" need to be defined too.
Now when I did a dry run of this code, the result produced was also not proper.
Input given was as follows:
enter the size of array
5
enter the numbers
12
10
34
2
6
Output received was as below:
the sorted array is below :
2 10 12 34 6
enter number to search
Now the output was incorrect.
Although it was in ascending order... still the last element would get missed. The twin for loops that are used need to be used in a different way. Please find the code that should be present in that section:
for (int i=0; i<=sizeArr; i++){
for (int j=0; j<sizeArr-1; j++) {
if (arr[j]>arr[j+1]) {
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
I hope that this works for you now.

how to print a number triangle in java

I need to produce a triangle as shown:
1
22
333
4444
55555
and my code is:
int i, j;
for(i = 1; i <= 5; i++)
{
for(j = 1; j <= i; j++)  
{          
System.out.print(i); 
}      
System.out.print("\n");        
}
Producing a triangle the opposite way
1
22
333
4444
55555
What do i need to do to my code to make it face the right way?
You need 3 for loops:
Upper-level loop for the actual number to be repeated and printed
first inner level for printing the spaces
second inner level for to print the number repeatedly
at the end of the Upper-level loop print new line
Code:
public void printReversedTriangle(int num)
{
for(int i=0; i<=num; i++)
{
for(int j=num-i; j>0; j--)
{
System.out.print(" ");
}
for(int z=0; z<i; z++)
{
System.out.print(i);
}
System.out.println();
}
}
Output:
1
22
333
4444
55555
666666
I came across this problem in my AP CS class. I think you may be starting to learn how to program so heres what I'd do without giving you the answer.
Use a loop which removes the number of spaces each iteration. The first time through you would want to print four spaces then print 1 one time(probably done in a separate loop).
Next time through one less space, but print i one more time.
You need to print some spaces. There is a relation between the number of spaces you need and the number (i) you're printing. You can print X number of spaces using :
for (int k = 0; k < numSpaces; k++)
{
System.out.print(" ");
}
So in your code:
int i, j;
for(i = 1; i <= 5; i++)
{
// Determine number of spaces needed
// print spaces
for(j = 1; j <= i; j++)
{
System.out.print(i);
}
System.out.print("\n");
}
use this code ,
int i, j,z;
boolean repeat = false;
for (i = 1; i <= 5; i++) {
repeat = true;
for (j = 1; j <= i; j++) {
if(repeat){
z = i;
repeat = false;
while(z<5){
System.out.print(" ");
z++;
}
}
System.out.print(i);
}
{
System.out.print("\n");
}
}
You can use this:
int i, j;
int size = 5;
for (i = 1; i <= size; i++) {
if (i < size) System.out.printf("%"+(size-i)+"s", " ");
for (j = 1; j <= i; j++) {
System.out.print(i);
}
System.out.print("\n");
}
This line:
if (i < size) System.out.printf("%"+(size-i)+"s", " ");
Is going to print the left spaces.
It uses the old printf with a fixed sized string like 5 characters: %5s
Try it here: http://ideone.com/jAQk67
i'm having trouble sometimes as well when it's about formatting on console...
...i usually extract that problem into a separate method...
all about how to create the numbers and spacing has been posted already, so this might be overkill ^^
/**
* creates a String of the inputted number with leading spaces
* #param number the number to be formatted
* #param length the length of the returned string
* #return a String of the number with the size length
*/
static String formatNumber(int number, int length){
String numberFormatted = ""+number; //start with the number
do{
numberFormatted = " "+numberFormatted; //add spaces in front of
}while(numberFormatted.length()<length); //until it reaches desired length
return formattedNumber;
}
that example can be easily modified to be used even for Strings or whatever ^^
Use three loops and it will produce your required output:
for (int i=1;i<6 ;i++ )
{
for(int j=5;j>i;j--)
{
System.out.print(" ");
}
for(int k=0;k<i;k++)
{
System.out.print(i);
}
System.out.print("\n");
}
Your code does not produce the opposite, because the opposite would mean that you have spaces but on the right side. The right side of your output is simply empty, making you think you have the opposite. You need to include spaces in order to form the shape you want.
Try this:
public class Test{
public static void main (String [] args){
for(int line = 1; line <= 5; line++){
//i decreases with every loop since number of spaces
//is decreasing
for(int i =-1*line +5; i>=1; i--){
System.out.print(" ");
}
//j increases with every loop since number of numbers
//is decreasing
for(int j = 1; j <= line; j++){
System.out.print(line);
}
//End of loop, start a new line
System.out.println();
}
}
}
You approached the problem correctly, by starting with the number of lines. Next you have to make a relation between the number of lines (the first for loop) and the for loops inside. When you want to do that remember this formula:
Rate of change*line + X = number of elements on line
You calculate rate of change by seeing how the number of elements change after each line. For example on the first line you have 4 spaces, on the second line you have 3 spaces. You do 3 - 4 = -1, in other words with each line you move to, the number of spaces is decreasing by 1. Now pick a line, let's say second line. By using the formula you will have
-1(rate of change) * 2(line) + X = 3(how many spaces you have on the line you picked).
You get X = 5, and there you go you have your formula which you can use in your code as you can see on line 4 in the for loop.
for(int i = -1 * line +5; i >= 1; i--)
You do the same for the amount of numbers on each line, but since rate of change is 1 i.e with every line the amount of numbers is increasing by 1, X will be 0 since the number of elements is equal to the line number.
for(int j = 1; j <= line; j++){

Categories

Resources