How do I take null spaces out of an array? - java

I have to make a program that takes duplicate characters from an input array and prints out a new array with all unique characters.
It all works. Except when characters are taken out, it leaves an empty box at the end of that new array.
public class Deleter {
public static void main (String[] args){
Scanner keyboard = new Scanner(System.in);
char[] initialInputArray = new char[15];
System.out.println("How many characters do you wish to enter?");
int size = keyboard.nextInt();
while ( size > initialInputArray.length ) {
System.out.println("Error. Enter smaller number.");
size = keyboard.nextInt();
}
if( initialInputArray.length <= 15) {
for ( int counter = 0; counter < size; counter++ ){
initialInputArray[counter] = keyboard.next().charAt(0);
}
{
}
}
deleteRepeats(initialInputArray, size);
//Comeback to print out array
{
for ( int helloWorld = 0 ; helloWorld < size ; helloWorld ++)
System.out.print( initialInputArray[helloWorld] );
}
}
//"deleteReapets" method begins, looking for repeated user inputs
public static char[] deleteRepeats (char[] methodArray, int sizeTwo) {
if (sizeTwo == 0)
return methodArray;
if (sizeTwo == 1)
return methodArray;
int uniqueCharacter = 1;
//Start at the second entered character.
for (int x = 1; x < sizeTwo; ++x) {
int y;
for (y = 0; y < uniqueCharacter; ++y) {
if (methodArray[x] == methodArray[y]) break; // break if we find duplicate.
}
if (y == uniqueCharacter) {
methodArray[uniqueCharacter] = methodArray[x]; // add
++uniqueCharacter; // increment uniqueCharacter...[0,uniqueCharacter) is still "unique char list"
}
}
while ( uniqueCharacter < sizeTwo ) {
methodArray[uniqueCharacter] = 0;
uniqueCharacter++;
}
return methodArray;
}
}

That empty box is the null characters that you added at the end of the array. You are printing them because you are not adjusting size according to the number of unique characters (which can be less than the input size). Since you aren't creating a new array, you don't need to return a char [] from deleteRepeats. Instead, you can return the number of unique characters. That way, the calling program knows how many to print.
If your assignment requires that deleteRepeats return a char[], then you should allocate a new array that has a length exactly equal to uniqueCharacter, copy the unique characters to it, and return that. The calling program can just print that new (and shorter) array, rather than printing the first size elements of the input.

Probably the easiest way would be to make a new array to the size of your array of chars and then copy all of the chars into that. The problem with arrays is that once they have been initialized they can't be re sized. If your are familiar with arrayLists I would recommend using them. But if not try something like this...
int count = 0;
for(int i = 0; i < initialInputArray.size; i++){
count++;
}
char[] newArray = new char[count];
for(int i = 0; i < count; i++){
newArray[i] = initialInputArray[i];
}

I would suggest using a HashSet to remove duplicates and wrapping your char to Character. Something like this:
public static Character[] deleteRepeats (char[] methodArray){
HashSet<Character> set = new HashSet<Character>();
for(int index = 0; index < methodArray.length; index++){
set.add(methodArray[index]);
}
return set.toArray(new Character[set.size()]);
}
So in your main method, what you would do is something like this:
Character[] charArray = deleteRepeats(methodArray);
for(int index = 0; index < charArray.length; index++){
System.out.println(charArray[index]);
}

Related

returning all string values that meet the condition

Not sure how to set up this method which gets as parameter a String array and has to return in a new array all values that meet the following condition:
25% of characters in every element of array are numbers;
public static String[] returnSentence(String[] str){
int nrOfWords = str.length;
int count = 0;
for(int i = 0; i < nrOfWords; i++){
for(int j = 0; j < str[i].length; j++){
}
}
}
I had an idea that it should be something like this but cant format the code to test the condition...
Your question basically boils down to figuring out how many characters in the String fullfil a given condition, and how many do not.
There is two ways to do this:
1) Simply count the characters:
int numPositiveChars = 0;
int numNegativeChars = 0;
for (int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if (/*check c here*/)
numPositiveChars++;
else
numNegativeChars++;
}
In fact you don't even need to count the negative chars, because that value is simply s.length() - numPositiveChars.
2) Another approach would be to use regular expressions, e.g. by removing all non-numerical characters and then get the character count:
int numPositiveChars = s.replaceAll("[^0-9]+", "").length();
This line will remove all characters from the String that are not numerical (not 0-9) and then return the length of the result (the number of characters that are numerical).
Once you have the number of chars that match your condition, calculating the percentage is trivial.
You need to just replace all non digits in each element and then compare the length like so :
public static List<String> returnSentence(String[] str) {
int nrOfWords = str.length;
List<String> result = new ArrayList<>();
for (int i = 0; i < nrOfWords; i++) {
if(str[i].replaceAll("\\D", "").length() == str[i].length() * 0.25){
result.add(str[i]);
}
}
return result; // If you want an array use : return result.toArray(String[]::new);
}
I would also use as result a List instead of array because you don't have any idea how many element is respect the condition.
If you want to solve with streaming it can be more easier :
public static String[] returnSentence(String[] str) {
return Arrays.stream(str)
.filter(s-> s.replaceAll("\\D", "").length() == s.length() * 0.25)
.toArray(String[]::new);
}
some thing like this
public static String[] returnSentence(String[] str){
int nrOfWords= str.length;
String[] temp_Str = new String[20];
int count = 0;
int k=0;
for(int i = 0;i<nrOfWords;i++){
for(int j = 0;j<str[i].length;j++){
if(Character.isAlphabetic(str[i].getcharat(j)))
{
count++;
}
if((count/100.0)*100>=25)
{ temp_Str[k]=str[i];
k++;
}
}
}
}

Iterator and regular for loop

I understand how iteration work but may be I need more knowledge about it. Can any one please show me the main difference between these two statements:
while (scanner.hasNext()) {
tokenizer = new StringTokenizer(scanner.nextLine());
numberOfItems = Integer.parseInt(tokenizer.nextToken());
int[] numbers = new int[numberOfItems];
for (int i:numbers) {
numbers[i] = Integer.parseInt(tokenizer.nextToken());
}
System.out.println(isJolly(numbers));
}
while (scanner.hasNext()) {
tokenizer = new StringTokenizer(scanner.nextLine());
numberOfItems = Integer.parseInt(tokenizer.nextToken());
int[] numbers = new int[numberOfItems];
for (int i = 0; i < numberOfItems; i++) {
numbers[i] = Integer.parseInt(tokenizer.nextToken());
}
System.out.println(isJolly(numbers));
}
why these giving me 2 different output?
You have created empty array (array filled with zeroes).
int[] numbers = new int[numberOfItems];
In case of
for ( int i = 0; i < numbers.length; i++ ) ...
i starts from 0 and on each iteration it is incremented (i++). Iterations are finished when i became equals or more than numbers.length (aka numberOfItems). So sequence of i values is 0,1,2,3,4,5,...
In case of
for (int i:numbers) {
You iterate on each value taken from array and you will get sequence of zeroes ( 0,0,0,0,0, ...).
And yours number[i] = will update only the number[0] element of resulting array.

Non-repeating random numbers inside array JAVA

I would like to generate 6 numbers inside an array and at the same time, having it compared so it will not be the same or no repeating numbers. For example, I want to generate 1-2-3-4-5-6 in any order, and most importantly without repeating. So what I thought is to compare current array in generated array one by one and if the number repeats, it will re-run the method and randomize a number again so it will avoid repeating of numbers.
Here is my code:
import javax.swing.*;
public class NonRepeat
{
public static void main(String args[])
{
int Array[] = new int [6];
int login = Integer.parseInt(JOptionPane.showInputDialog("ASD"));
while(login != 0)
{
String output="";
for(int index = 0; index<6; index++)
{
Array[index] = numGen();
for(int loop = 0; loop <6 ; loop++)
{
if(Array[index] == Array[loop])
{
Array[index] = numGen();
}
}
}
for(int index = 0; index<6; index++)
{
output += Array[index] + " ";
}
JOptionPane.showMessageDialog(null, output);
}
}
public static int numGen()
{
int random = (int)(1+Math.random()*6);
return random;
}
}
I've been thinking it for 2 hours and still cant generate 6 numbers without repeating.
Hope my question will be answered.
Btw, Im new in codes so please I just want to compare it using for loop or while loop and if else.
You can generate numbers from, say, 1 to 6 (see below for another solution) then do a Collections.shuffle to shuffle your numbers.
final List<Integer> l = new ArrayList<Integer>();
for (int j = 1; j < 7; j++ ) {
l.add( j );
}
Collections.shuffle( l );
By doing this you'll end up with a randomized list of numbers from 1 to 6 without having twice the same number.
If we decompose the solution, first you have this, which really just create a list of six numbers:
final List<Integer> l = new ArrayList<Integer>();
for (int j = 1; j < 7; j++ ) {
l.add( j );
}
So at this point you have the list 1-2-3-4-5-6 you mentioned in your question. You're guaranteed that these numbers are non-repeating.
Then you simply shuffle / randomize that list by swapping each element at least once with another element. This is what the Collections.shuffle method does.
The solutions that you suggested isn't going to be very efficient: depending on how big your list of numbers is and on your range, you may have a very high probability of having duplicate numbers. In that case constantly re-trying to generate a new list will be slow. Moreover any other solution suggesting to check if the list already contains a number to prevent duplicate or to use a set is going to be slow if you have a long list of consecutive number (say a list of 100 000 numbers from 1 to 100 000): you'd constantly be trying to randomly generate numbers which haven't been generated yet and you'd have more and more collisions as your list of numbers grows.
If you do not want to use Collections.shuffle (for example for learning purpose), you may still want to use the same idea: first create your list of numbers by making sure there aren't any duplicates and then do a for loop which randomly swap two elements of your list. You may want to look at the source code of the Collections.shuffle method which does shuffle in a correct manner.
EDIT It's not very clear what the properties of your "random numbers" have to be. If you don't want them incremental from 1 to 6, you could do something like this:
final Random r = new Random();
final List<Integer> l = new ArrayList<Integer>();
for (int j = 0; j < 6; j++ ) {
final int prev = j == 0 ? 0 : l.get(l.size() - 1);
l.add( prev + 1 + r.nextInt(42) );
}
Collections.shuffle( l );
Note that by changing r.nextInt(42) to r.nextInt(1) you'll effectively get non-repeating numbers from 1 to 6.
You have to check if the number already exist, you could easily do that by putting your numbers in a List, so you have access to the method contains. If you insist on using an array then you could make a loop which checks if the number is already in the array.
Using ArrayList:
ArrayList numbers = new ArrayList();
while(numbers.size() < 6) {
int random = numGen(); //this is your method to return a random int
if(!numbers.contains(random))
numbers.add(random);
}
Using array:
int[] numbers = new int[6];
for (int i = 0; i < numbers.length; i++) {
int random = 0;
/*
* This line executes an empty while until numGen returns a number
* that is not in the array numbers yet, and assigns it to random
*/
while (contains(numbers, random = numGen()))
;
numbers[i] = random;
}
And add this method somewhere as its used in the snippet above
private static boolean contains(int[] numbers, int num) {
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == num) {
return true;
}
}
return false;
}
Here is the solution according to your code -
You just need to change the numGen method -
public static int numGen(int Array[])
{
int random = (int)(1+Math.random()*6);
for(int loop = 0; loop <Array.length ; loop++)
{
if(Array[loop] == random)
{
return numGen(Array);
}
}
return random;
}
Complete code is -
import javax.swing.*;
public class NonRepeat
{
public static void main(String args[])
{
int login = Integer.parseInt(JOptionPane.showInputDialog("ASD"));
while(login != 0)
{
int Array[] = new int [6];
String output="";
for(int index = 0; index<6; index++)
{
Array[index] = numGen(Array);
}
for(int index = 0; index<6; index++)
{
output += Array[index] + " ";
}
JOptionPane.showMessageDialog(null, output);
}
}
public static int numGen(int Array[])
{
int random = (int)(1+Math.random()*6);
for(int loop = 0; loop <Array.length ; loop++)
{
if(Array[loop] == random)
{
return numGen(Array);
}
}
return random;
}
}
Use List instead of array and List#contains to check if number is repeated.
you can use a boolean in a while loop to identify duplicates and regenerate
int[] array = new int[10]; // array of length 10
Random rand = new Random();
for (int i = 0 ; i < array.length ; i ++ ) {
array[i] = rand.nextInt(20)+1; // random 1-20
boolean found = true;
while (found) {
found = false;
// if we do not find true throughout the loop it will break (no duplicates)
int check = array[i]; // check for duplicate
for (int j = 0 ; j < i ; j ++) {
if ( array[j] == check ) {
found = true; // found duplicate
}
}
if (found) {
array[i] = rand.nextInt(20)+1 ; // replace
}
}
}
System.out.println(Arrays.toString(array));
You may use java.util.Random. And please specify if you want any random number or just the number 1,2,3,4,5,6. If you wish random numbers then , this is a basic code:
import java.util.*;
public class randomnumber
{
public static void main(String[] args)
{
Random abc = new Random();
int[] a = new int[6];
int limit = 100,c=0;
int chk = 0;
boolean y = true;
for(;c < 6;)
{
int x = abc.nextInt(limit+1);
for(int i = 0;i<a.length;i++)
{
if(x==a[i])
{
y=false;
break;
}
}
if(y)
{
if(c!=0)if(x == (a[c-1]+1))continue;
a[c]=x;
c++;
}
}
for (Integer number : a)
{
System.out.println(number);
}
}
}
if you don't understand the last for loop , please tell , i will update it.
Use List and .contains(Object obj) method.
So you can verify if list has the random number add before.
update - based on time you can lost stuck in random loop.
List<Integer> list = new ArrayList<Integer>();
int x = 1;
while(x < 7){
list.add(x);
x++;
}
Collections.shuffle(list);
for (Integer number : list) {
System.out.println(number);
}
http://docs.oracle.com/javase/7/docs/api/java/util/List.html#contains(java.lang.Object)

Java: Creating a Delimiter Method that has Input/Output

I'm working on a study problem from class and essentially it reads a string, and a character. The character is the delimiter. It will then search the string for the delimiter and create an array in equal length to the number of times the delimiter is found. It then assigns each character or string to its own spot in the array and returns it.
Maybe I am over thinking things, but the just of it is to not rely on the various string methods and to sort of create your own. How can I get this method to only assign the string/char found in the one that is read to one position in the array and not all as well as stop it from adding unnecessary output? Help/Suggestions greatly appreciated
public static String[] explode(String s, char d){
String []c;
int count = 1;
//checks to see how many times the delimter appears in the string and creates an array of corresponding size
for(int i = 0; i < s.length(); i++){
if(d == s.charAt(i))
count ++;
}
c = new String [count];
//used for checking to make sure the correct number of elements are found
System.out.println(c.length);
//goes through the the input string "s" and checks to see if the delimiter is found
//when it is found it makes c[j] equal to what is found
//once it has cycled through the length of "s" and filled each element for c, it returns the array
for(int i = 0; i < s.length(); i++){
for(int j = 0; j < c.length; j++){
if(d == s.charAt(i))
c[j] += s.substring(i-1);
}
}
//provides output for the array [c] just to verify what was found
for(int y = 0; y < c.length; y++)
System.out.println(c[y]);
return c;
}
public static void main(String [] args){
String test = "a,b,c,d";
char key = ',';
explode(test,key);
}
^The following will output:
4
nulla,b,c,db,c,dc,d
nulla,b,c,db,c,dc,d
nulla,b,c,db,c,dc,d
nulla,b,c,db,c,dc,d
I'm aiming for:
4
a
b
c
d
Thank you
Perhaps you could try something like this:
public static void main(String[] args){
explode("a,b,c,d", ',');
}
public static void explode(final String string, final char delimiter){
int length = 1;
for(final char c : string.toCharArray())
if(delimiter == c)
length++;
if(length == 1)
return;
final String[] array = new String[length];
int index, prev = 0, i = 0;
while((index = string.indexOf(delimiter, prev)) > -1){
array[i++] = string.substring(prev, index);
prev = index+1;
}
array[i] = string.substring(prev);
System.out.println(length);
for(final String s : array)
System.out.println(s);
}
Output of the program above is:
4
a
b
c
d
Or if you want to utilize a List<String> instead (and Java 8), you could remove a couple of lines by doing something like this:
public static void explode(final String string, final char delimiter){
final List<String> list = new LinkedList<>();
int index, prev = 0;
while((index = string.indexOf(delimiter, prev)) > -1){
list.add(string.substring(prev, index));
prev = index+1;
}
list.add(string.substring(prev));
System.out.println(list.size());
list.forEach(System.out::println);
}

Printing letters in 2D arrays? First letter not showing

I'm hoping someone can answer this so I'll try to explain this well.
My goal is to generate a MAXIMUM of 3 unique vowels (AEIOU) on a line of 5 squares. I have made 25 squares using a 2D array (board[][]), but I want to do the first line first. Picture it like this:
Now, my problem is, whenever I try to generate random letters in my squares, the first letter doesn't show. For example I have E and O, O would only show in my squares, and not E. It's printing in my console, but not in my GUI.
Also, sometimes DUPLICATES of letters are showing. I don't know how to fix this :|
Here are the codes I've done so far:
String board[][] = new String[5][5];
String alphabet = "AEIOU";
int numArray[] = new int[5]; //where I can store random indices of alphabet
int finalIndex = 0;
int random = (int) (Math.random()*3) + 1; //random number of vowels to be generated
//this loop covers everything
for(int ctr = 0; ctr < random; ctr++) {
while(ctr != finalIndex) { //checks if there are any duplicates
int rand = (int) (Math.random()*4); //random position for the letter
numArray[ctr] = rand;
while(numArray[ctr] != numArray[finalIndex]) {
finalIndex++;
}
}
//finds the position of the letter in alphabet and converts it to String
char character = alphabet.charAt(numArray[ctr]);
String s = String.valueOf(character);
System.out.println(s);
//loop for putting the letters to the 2D array
for(int i = 0; i < board.length; i++) {
int gen = (int) (Math.random()*4); //random square for letter
for(int j = 0; j <= gen; j++) {
if(i == 0 && j < 5) { //row 1
board[i][gen] = s;
}
}
}
}
I decided not to put my GUI code anymore just to make things simpler.
Sorry I couldn't read what you had, so i tried this myself...
int rows = 5;
Character [] vowels = {'A','E','I','O','U'};
Character [][] board = new Character [vowels.length][rows];
for(int row = 0;row<rows;row++){
ArrayList<Character> tempVowels = new ArrayList<Character>(Arrays.asList(vowels));
int numVowPerLine = (int)Math.floor(Math.random()*4);
for(int j = 0;j<numVowPerLine;j++){
do{
int pos = (int)Math.floor(Math.random()*5);
if(board[row][pos] == null){
int temp = (int)Math.floor(Math.random()*tempVowels.size());
board[row][pos] = tempVowels.get(temp);
tempVowels.remove(temp);
break;
}
}while(true);
}
}

Categories