Shuffling strings in Java - java

While I am creating Java String shuffler, I am getting a problem:
program stucks somewhere.
I have to pass a sentence or a word through BufferedReader
I have to shuffle the word/sentence so that first element is the first letter, then last letter, then 2nd letter, then 2nd from the end till the job is done
2.1. If word/sentence length is odd, the middle character has to be put in the end of the word/sentence.
Have to print it out
Result should be like this:
My code;
public static void main(String[] args) {
String enteredValue = null;
int charArrayLength = 0;
System.out.println("Dāvis Naglis IRDBD11 151RDB286");
System.out.println("input string:");
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
enteredValue = br.readLine();
charArrayLength = enteredValue.length(); // length of array entered
char[] characters = new char[charArrayLength];
characters = enteredValue.toCharArray();
} catch (Exception e) {
e.printStackTrace();
}
char[] tempChars = new char[charArrayLength];
for (int i = 0; i <= charArrayLength - 1; i++) {
tempChars[i] = enteredValue.charAt(i);
}
}
/**
* Shuffles the char array if it's length is even
*
* #param array
*/
public static void shuffle(char[] array) {
char[] tempChars = null;
for (int j = 0; j <= array.length; j++) {
if ((array.length % 2 == 0) && (j < array.length)) { // array[j] == (array.length / 2) + 1
tempChars[j] = array[array.length - j];
} else if (array.length % 2 != 0) {
tempChars[array.length] = array[j];
} // end else if
} // end for
String shuffledSentence = new String(tempChars);
System.out.println(shuffledSentence);
}
Don't look at multiple line comments, haven't changed them since start.
Thanks in advance!

Shuffling made easy:
int len = array.length;
char[] tempArray = new char[len];
int i=0, j=0, k=len-1;
while (i<len) {
tempArray[i++] = array[j++];
if (i<len) {
tempArray[i++] = array[k--];
}
}

Wow. Your algorithm is too complex for this problem!
Try this for shuffling:
int n = array.length;
char[] resChars = new char[n];
boolean flag = false;
if (n % 2 != 0) {
flag = true;
char tmp = array[n / 2];
}
for (int j = 0; j < n - 1; j += 2) {
resChars[j] = array[j / 2];
resChars[j + 1] = array[n - 1 - (j / 2)]
}
if (flag)
resChars[n - 1] = tmp;

You can try something like this:
String str;
char[] chars = str.toCharArray();
List<Character> list = new ArrayList<>();
for (char aChar : chars) {
list.add(aChar);
}
Collections.shuffle(list);
String result = list.toString().replaceAll("[\\[\\],]", "");

Your program doesn't stuck, it exits properply.
Process finished with exit code 0
There is no more work to do for the process, since you don't call
your static shuffle method.
In addition, as the others already answered, your static shuffle method needs some design
refactoring.

Related

Generate all possible string combinations by replacing the hidden “#” number sign

My task is to generates all possible combinations of that rows without the hidden # number sign. The input is XOXX#OO#XO and here is the example of what the output should be:
XOXXOOOOXO
XOXXOOOXXO
XOXXXOOOXO
XOXXXOOXXO
I am only allowed to solve this solution iteratively and I am not sure how to fix this and have been working on this code for a week now.
Here is my code:
import java.lang.Math;
public class help {
public static void main(String[] args) {
String str = new String("XOXX#OO#XO");
UnHide(str);
}
public static void UnHide(String str) {
//converting string to char
char[] chArr = str.toCharArray();
//finding all combinations for XO
char[] xo = new char[]{'X', 'O'};
int count = 0;
char perm = 0;
String s = "";
//finding amount of times '#' appears in string
for (int i = 0; i < str.length(); i++) {
if (chArr[i] == '#')
count++;
}
int[] combo = new int[count];
int pMax = xo.length;
while (combo[0] < pMax) {
// print the current permutation
for (int k = 0; k < count; k++) {
//print each character
//System.out.print(xo[combo[i]]);
perm = xo[combo[k]];
s = String.valueOf(perm);
char[] xoArr = s.toCharArray();
String strChar = new String(xoArr);
//substituting '#' to XO combo
for (int i = 0; i < chArr.length; i++) {
for (int j = 0; j < s.length(); j++) {
if (chArr[i] == '#') {
chArr[i] = xoArr[j];
strChar = String.copyValueOf(chArr);
i++;
}
}
i++;
if (i == chArr.length - 1) {
System.out.println(strChar);
i = 0;
}
}
}
System.out.println(); //print end of line
// increment combo
combo[count - 1]++; // increment the last index
//// if increment overflows
for (int i = count - 1; combo[i] == pMax && i > 0; i--) {
combo[i - 1]++; // increment previous index
combo[i] = 0; // set current index to zero
}
}
}
}
Since your input has 2 #'s, there are 2n = 4 permutations.
If you count from 0 to 3, and look at the numbers in binary, you get 00, 01, 10, and 11, so if you use that, inserting O for 0 and X for 1, you can do this using simple loops.
public static void unHide(String str) {
int count = 0;
for (int i = 0; i < str.length(); i++)
if (str.charAt(i) == '#')
count++;
if (count > 30)
throw new IllegalArgumentException("Too many #'s found. " + count + " > 30");
char[] buf = str.toCharArray();
for (int permutation = 0, end = 1 << count; permutation < end; permutation++) {
for (int i = buf.length - 1, bit = 0; i >= 0; i--)
if (str.charAt(i) == '#')
buf[i] = "OX".charAt(permutation >>> bit++ & 1);
System.out.println(buf);
}
}
Test
unHide("XOXX#OO#XO");
Output
XOXXOOOOXO
XOXXOOOXXO
XOXXXOOOXO
XOXXXOOXXO
You can iteratively generate all possible combinations of strings using streams as follows:
public static String[] unHide(String str) {
// an array of substrings around a 'number sign'
String[] arr = str.split("#", -1);
// an array of possible combinations
return IntStream
// iterate over array indices
.range(0, arr.length)
// append each substring with possible
// combinations, except the last one
// return Stream<String[]>
.mapToObj(i -> i < arr.length - 1 ?
new String[]{arr[i] + "O", arr[i] + "X"} :
new String[]{arr[i]})
// reduce stream of arrays to a single array
// by sequentially multiplying array pairs
.reduce((arr1, arr2) -> Arrays.stream(arr1)
.flatMap(str1 -> Arrays.stream(arr2)
.map(str2 -> str1 + str2))
.toArray(String[]::new))
.orElse(null);
}
// output to the markdown table
public static void main(String[] args) {
String[] tests = {"XOXX#OOXO", "XOXX#OO#XO", "#XOXX#OOXO#", "XO#XX#OO#XO"};
String header = String.join("</pre> | <pre>", tests);
String matrices = Arrays.stream(tests)
.map(test -> unHide(test))
.map(arr -> String.join("<br>", arr))
.collect(Collectors.joining("</pre> | <pre>"));
System.out.println("| <pre>" + header + "</pre> |");
System.out.println("|---|---|---|---|");
System.out.println("| <pre>" + matrices + "</pre> |");
}
XOXX#OOXO
XOXX#OO#XO
#XOXX#OOXO#
XO#XX#OO#XO
XOXXOOOXOXOXXXOOXO
XOXXOOOOXOXOXXOOOXXOXOXXXOOOXOXOXXXOOXXO
OXOXXOOOXOOOXOXXOOOXOXOXOXXXOOXOOOXOXXXOOXOXXXOXXOOOXOOXXOXXOOOXOXXXOXXXOOXOOXXOXXXOOXOX
XOOXXOOOOXOXOOXXOOOXXOXOOXXXOOOXOXOOXXXOOXXOXOXXXOOOOXOXOXXXOOOXXOXOXXXXOOOXOXOXXXXOOXXO
The process would probably be best to calculate the number of permutations, then loop through each to define what combination of characters to use.
For that, we'll have to divide the permutation number by some value related to the index of the character we're replacing, which will serve as the index of the character to swap it to.
public static void test(String word) {
// Should be defined in class (outside method)
String[] replaceChars = {"O", "X"};
char replCharacter = '#';
String temp;
int charIndex;
int numReplaceable = 0;
// Count the number of chars to replace
for (char c : word.toCharArray())
if (c == replCharacter)
numReplaceable++;
int totalPermutations = (int) Math.pow(replaceChars.length, numReplaceable);
// For all permutations:
for (int permNum = 0; permNum < totalPermutations; permNum++) {
temp = word;
// For each replacement character in the word:
for (int n = 0; n < numReplaceable; n++) {
// Calculate the character to swap the nth replacement char to
charIndex = permNum / (int) (Math.pow(replaceChars.length, n))
% replaceChars.length;
temp = temp.replaceFirst(
replCharacter + "", replaceChars[charIndex]);
}
System.out.println(temp);
}
}
Which can produces:
java Test "#TEST#"
OTESTO
XTESTO
OTESTX
XTESTX
This can also be used with any number of characters, just add more to replaceChars.

Changing every 5th character in a String java

I'm trying to get a function to take a String and change every 5th character to a 'z'. For whatever reason the first character changed is always the 6th character and I can't figure out why. There's also an error if the string is divisible by 5, which is either because it starts on the 6th character or because my loop iteration goes one too far.
I've messed with the loop iteration but just can't see why it's starting on the 6th character.
public static String change5thPosition(String s) {
int fives = (int) Math.floor((s.length() / 5));
System.out.println(fives);
char[] chars = s.toCharArray();
for (int i = 0; i <= fives; i++) {
if (i != 0)
chars[i * 5] = 'z';
}
String returnString = new String(chars);
return returnString;
}
Input example:
all mimsy were the baragroves
Expected output:
all zimsyzwerezthe zbragzoves
Actual output:
all mzmsy zere zhe bzragrzves
Edit: Thanks for the help. here is my updated code:
public static String change5thPosition(String s) {
char[] chars = s.toCharArray();
for (int i = 4; i < s.length(); i = i + 5) {
chars[i] = 'z';
}
String returnString = new String(chars);
return returnString;
}
Your code changes:
i=1 : chars[1 * 5 = 5]
i=2 : chars[2 * 5 = 10]
... and so on.
But since arrays are indexed starting with 0, you actually want to change the characters at 4,9,14, ....
So just subtract 1.
chars[i*5 - 1] = 'z';
These "off by one" errors are quite common in programming, and you'll learn to anticipate them.
On a side note, there's no need for:
for(int i=0; i<=fives; i++){
if (i!=0) {
...
}
}
... when you can just start i at 1:
for(int i=1; i<=fives; i++){
...
}
You could also avoid having to multiply, by incrementing in fives:
for(int i=4, i < chars.length; i += 5) {
char[i] = 'z';
}
Simply add a -1 to your index.
public static String change5thPosition(String s){
int fives = (int)Math.floor((s.length()/5));
System.out.println(fives);
char[] chars = s.toCharArray();
for(int i=0; i<=fives; i++){
if (i!=0)
chars[i*5 -1]='z';
}
String returnString = new String(chars);
return returnString;
}
A simple loop will do the Job. Take care of the index and avoid complex calculations.
String n = "all mimsy were the baragroves";
char[] s = n.toCharArray();
for(int i = 4;i<s.length;i+=5){
s[i]='z';
}
System.out.println(s);
You can try this code.
public class Simple {
public static void main(String args[]) {
System.out.println(change5thPosition("all mimsy were the baragroves"));
}
public static String change5thPosition(String s) {
int fives = (int) Math.floor((s.length() / 5));
System.out.println(fives);
char[] chars = s.toCharArray();
int index = 1;
StringBuilder myvar = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (index == 5) {
myvar.append("z");
index = 1;
} else {
myvar.append(c);
index++;
}
}
return myvar.toString();
}
}

Even after using a global static array my values of the array are changing in java. How to overcome it?

In this code I am having some problem as I have marked using a loop which is printing some values. I am storing them in an array as mentioned and am trying to print the values in another function. But even after using the global array the value of the array is changing.
I am not able to figure out the problem. Please help me out.
import java.io.*;
import java.util.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
// Java program to print all permutations of a
// given string.
public class test3
{
static int[] val = new int[100] ; //array declaration as global
public static void main(String[] args)
{
System.out.println("An incremented value");
for(int i=2;i<=2;i++) {
String p="";
for(int j=0;j<=i;j++) {
for(int m=0;m<j;m++) {
p=p+"&";
}
for(int m=0;m<i-j;m++) {
p=p+"|";
}
printAllPermutations(p);
p="";
}
}
System.out.println();
for(int xy=0;xy<32;xy++)
System.out.print("["+xy+"]"+"="+val[xy]+" "); //trying to print the array
}
static void print(char[] temp) {
String a="";
System.out.println();
for (int i = 0; i < temp.length; i++)
{ System.out.print(temp[i]);
a=a+temp[i];}
System.out.print(" "+"opr:"+temp.length+" ");
final int N = temp.length+1;
/*===================CODE PROBLEM PART START=======================*/
for (int i = 0; i < (1 << N); i++) {
// System.out.println(zeroPad(Integer.toBinaryString(i), N));
String b=zeroPad(Integer.toBinaryString(i), N)+"";
// System.out.println("a: "+a+" b:"+b);
char[] arrayA = b.toCharArray();
char[] arrayB = a.toCharArray();
StringBuilder sb = new StringBuilder();
int ii = 0;
while( ii < arrayA.length && ii < arrayB.length){
sb.append(arrayA[ii]).append(arrayB[ii]);
++ii;
}
for(int j = ii; j < arrayA.length; ++j){
sb.append(arrayA[j]);
}
for(int j = ii; j < arrayB.length; ++j){
sb.append(arrayB[j]);
}
//System.out.println(sb.toString());
try {
ScriptEngineManager sem = new ScriptEngineManager();
ScriptEngine se = sem.getEngineByName("JavaScript");
String myExpression = sb.toString();
// System.out.print(se.eval(myExpression));
val[i]=(int)(se.eval(myExpression)); //inserting array value
System.out.print(val[i]); //NEED TO HAVE THESE VALUES IN THE 1-D ARRAY
// System.out.print(val[i]);
} catch (ScriptException e) {
System.out.println("Invalid Expression");
e.printStackTrace();}
}
/*===================CODE PROBLEM PART END========================*/
//
}
//unchangable = rest of the function
static int factorial(int n) {
int f = 1;
for (int i = 1; i <= n; i++)
f = f * i;
return f;
}
static int calculateTotal(char[] temp, int n) {
int f = factorial(n);
// Building HashMap to store frequencies of
// all characters.
HashMap<Character, Integer> hm =
new HashMap<Character, Integer>();
for (int i = 0; i < temp.length; i++) {
if (hm.containsKey(temp[i]))
hm.put(temp[i], hm.get(temp[i]) + 1);
else
hm.put(temp[i], 1);
}
// Traversing hashmap and finding duplicate elements.
for (Map.Entry e : hm.entrySet()) {
Integer x = (Integer)e.getValue();
if (x > 1) {
int temp5 = factorial(x);
f = f / temp5;
}
}
return f;
}
static void nextPermutation(char[] temp) {
// Start traversing from the end and
// find position 'i-1' of the first character
// which is greater than its successor.
int i;
for (i = temp.length - 1; i > 0; i--)
if (temp[i] > temp[i - 1])
break;
// Finding smallest character after 'i-1' and
// greater than temp[i-1]
int min = i;
int j, x = temp[i - 1];
for (j = i + 1; j < temp.length; j++)
if ((temp[j] < temp[min]) && (temp[j] > x))
min = j;
// Swapping the above found characters.
char temp_to_swap;
temp_to_swap = temp[i - 1];
temp[i - 1] = temp[min];
temp[min] = temp_to_swap;
// Sort all digits from position next to 'i-1'
// to end of the string.
Arrays.sort(temp, i, temp.length);
// Print the String
print(temp);
}
static void printAllPermutations(String s) {
// Sorting String
char temp[] = s.toCharArray();
Arrays.sort(temp);
// Print first permutation
print(temp);
// Finding the total permutations
int total = calculateTotal(temp, temp.length);
for (int i = 1; i < total; i++)
nextPermutation(temp);
}
static String zero(int L) {
return (L <= 0 ? "" : String.format("%0" + L + "d", 0));
}
static String zeroPad(String s, int L) {
return zero(L - s.length()) + s;
}
}
The output that I am getting is
An incremented value
|| opr:2 01111111 //WANT TO STORE THESE 32 VALUES IN 1 D ARRAY
&| opr:2 01010111 // AND PRINT THEM OUT
|& opr:2 00011111
&& opr:2 00000001
[0]=0 [1]=0 [2]=0 [3]=0 [4]=0 [5]=0 [6]=0 [7]=1 [8]=0 [9]=0 [10]=0 [11]=0 [12]=0 [13]=0 [14]=0 [15]=0 [16]=0 [17]=0 [18]=0 [19]=0 [20]=0 [21]=0 [22]=0 [23]=0 [24]=0 [25]=0 [26]=0 [27]=0 [28]=0 [29]=0 [30]=0 [31]=0
what I need to do is to store those 32 values in 1 D array for further operation but while doing it all the array values displays 0 only except [7]. I dont know whats going on here.
Reference types are not bound to local scopes, just because your array is static to the class it does not mean that changing the values in one function will not change the values in the actual array. The reference to your array as a parameter will be a copy, but the reference is still "pointing" on an actual object, which is not a copy bound to your local scope.
If you want to save two different states of the array, you will have to save them yourself.

Java stdin not prompting program to run

I am working on a Merge-sort algorithm, and I am currently trying to test if it works.
It should be controlled through stdin with the input format:
array length
element values (separated by " ")
However, when typing in:
3
17 10 3
Nothing happens, and hitting enter, just get me to the next line in the console.
I get no error message (unless I type in wrong input), and so I have a hard time figuring out why the script is not prompted to run with the input given.
(Code is copied below)
package merge;
import java.io.*;
import java.util.*;
public class MergeSort
{
// This method takes two sorted arrays of integers as input parameters
// and it should return one sorted array of integers.
public int[] merge(int[] A1, int[] A2) {
int[] C = new int[A1.length + A2.length];
int i = 0, j = 0, k = 0;
while (i < A1.length && j < A2.length)
C[k++] = A1[i] < A2[j] ? A1[i++] : A2[j++];
while (i < A1.length)
C[k++] = A1[i++];
while (j < A2.length)
C[k++] = A2[j++];
return C;
}
// This method takes an array of integers as input parameter,
// and it should then return the integers sorted
// in ascending order using the MergeSort algorithm.
private int[] sort(int[] numbers) {
//pointers
int i = 0, j = 0, k = 0;
// reference values
int half = numbers.length / 2;
int[] sorted = new int[numbers.length];
if (numbers.length <= 1){
return numbers;
}
//left part of 'numbers'
int[] left = new int[half];
int[] right;
//right part of 'numbers'
if (numbers.length % 2 != 0){
right = new int[half+1];
j = half + 1;
}
else{
right = new int[half];
j = half;
}
//fills out left half of array with values from input array
while (i < half)
left[i] = numbers[i];
i++;
//fills out right half of array with values from input array
while (j < numbers.length)
right[j] = numbers[k];
j++; k++;
left = sort(left);
right = sort(right);
merge(left,right);
return sorted;
}
// ##################################################
// # Stdin part. #
// ##################################################
public static void main(String[] args) throws IOException {
new MergeSort().run();
}
private void run() throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int[] numbers = readIntArray(in);
numbers = sort(numbers);
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}
}
private int[] readIntArray(BufferedReader in) throws IOException {
int length = Integer.parseInt(in.readLine());
int[] array = new int[length];
StringTokenizer st = new StringTokenizer(in.readLine());
for (int i = 0; i < length; i++) {
array[i] = Integer.parseInt(st.nextToken());
}
return array;
}
}
You call readLine() two times, resulting in an attempt to read two lines on the standard input.

Swapping elements in ArrayList

I want to write a method, which takes a String and swaps each pair of characters in it and then concatenates them into a new String. Please let me know how to fix this code (or write a new better one):
static String s;
public static void proc(String w) {
ArrayList k = new ArrayList();
ArrayList m = new ArrayList();
System.out.println(w.length());
int j = 0;
//test arraylist to check if string is written into arraylist
for (int i = 0; i < w.length(); i++){
k.add(w.charAt(i));
}
String p = k.get(2).toString();
System.out.println(p);
//here starts the logic of my app
for (int n = 0; n < w.length(); n++){
String v = k.get(n).toString();
if (n == 0){
m.add(1, v);
}
else if (n == 1){
m.add(0, v);
}
else if ((n % 2) == 0){
m.add(n+1, v);
}
else {
m.add(n, v);
}
}
}
public static void main(String[] args){
s = "tests";
proc(s);
}
Hi this is not a homework, but am doing exercises from a book. Anyway using code provided by Jon managed to work on my own - it may be not as much elegant but is doing the job using dynamic sizing as well:
public static void proc(String w) {
ArrayList k = new ArrayList();
ArrayList g = new ArrayList();
String h = "";
for (int i = 0; i < w.length(); i++){
char temp = w.charAt(i);
k.add(i, temp);
}
for (int i = 0; i < w.length(); i++){
if (i == 0){
h = k.get(1).toString();
g.add(h);
}
else if (i == 1){
h = k.get(0).toString();
g.add(h);
}
else if ((i % 2) == 0){
h = k.get(i+1).toString();
g.add(h);
}
else if ((i % 2) == 1){
h = k.get(i-1).toString();
g.add(h);
}
}
System.out.println(g.toString());
}
public static void main(String[] args){
s = "test";
proc(s);
}
I haven't tried to go through exactly how your code is trying to work, but it looks unnecessarily complicated to me. Given that you don't need dynamic sizing, you can do this more easily with an array:
public static String swapPairs(String input) {
char[] chars = input.toCharArray();
for (int i = 0; i < chars.length - 1; i += 2) {
char tmp = chars[i];
chars[i] = chars[i + 1];
chars[i + 1] = tmp;
}
return new String(chars);
}
Note that while this will work for "simple" characters (where each element of the array is independent of the rest), it doesn't try to take any form of "composite" characters into consideration, such as characters formed from two UTF-16 code units (surrogate pairs) or combined characters such as "e + acute accent". Doing this sort of contextually-aware swapping would take a lot more effort.
This looks like homework, so I'll limit my answer to a couple of hints.
I would accumulate the result in a StringBuilder (called sb in what follows).
I would have a loop (for i = 0; i < w.length(); i += 2). In this loop I would do two things:
if i + 1 is within the bounds of the string, I'd append the i + 1-th character to sb;
append the i-th character to sb.
At the end, call sb.toString().

Categories