How to rearrange string after permutation - java

I'm using the code below to permute a string according to a specific table.
public static void main(String[] args) {
int[] IP = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 };
String text = "00000001 00100011 01000101 01100111 10001001 10101011 11001101 11101111".replace(" ", "");
text = Permute(text,IP);
System.out.println(text);
}
public static String Permute(String text,int [] table )
{
String keys = "0" + text;
StringBuilder sb = new StringBuilder ();
for (int i = 1 ; i <= table.length; i++)
{
sb.append(keys.charAt(table[i-1]));
}
return sb.toString();
}
UPDATED:Any idea to create another method to get the original string back? Something like :
public static String GetoriginalText(String TextafterPermutation,int [] table )

You can use a chararray that you populate according to your table mapping
public static String RePermute(final String text, final int[] table) {
final String keys = text;
char[] chararray = new char[table.length];
for (int i = 0; i < keys.length() && i < table.length; i++) {
chararray[table[i]-1] = keys.charAt(i);
}
return new String(chararray);
}
This code is iterating through your text, and writes the char of the current iteration at the chararray place specified in your table.
Note: There are some problems in your code that i left untouched.
For example I really don't get why you allways put "0" in front of your text.
Also you might want to handle situations where the passed text and table differ in length.
Edit: I removed the part where you add "0" in front of your passed text and instead changed the loop to start at i=0 instead i=1.

You can simplify your algorithm to use array of chars instead of StringBuilder:
public static String permute(String text,int [] table )
{
char[] chars = new char[table.length];
for (int i = 0 ; i < table.length; i++) {
chars[i] = text.charAt(table[i]-1);
}
return new String(chars);
}
After that reverse algorithm is more obvious. You just need to make reverse assignment:
public static String undo(String text,int [] table ) {
char[] chars = new char[table.length];
for (int i = 0; i < table.length; i++)
{
chars[table[i]-1] = text.charAt(i);
}
return new String(chars);
}

In the statement text = Permute(text,IP); you are assigning reference of String object returning from Permute function, so the original reference which text variable was holding is replaced by new reference returned by Permute function.
If you want to keep the original reference which text was holding, just use any other variable like String output = Permute(text,IP);.
You could use a simple program as mentioned below:
public static String dePermute(String text, int[] table){
String keys = text;
System.out.println(table.length);
String[] str = new String[table.length];
for (int i = 1; i <= table.length; i++) {
System.out.println("Coming "+table[i - 1]);
str[table[i - 1]-1] = ""+keys.charAt(i-1);
//sb.append(keys.charAt(table[i - 1]));
}
return Arrays.toString(str).replace("[", "").replace("]", "").replace(",", "").replace(" ", "");
}
You can use the concept explained in this program. I have just reverse the process which you are doing in Permute function.

assuming your permutation table doesn't change you can do this:
public static String GetoriginalText(String TextafterPermutation,int [] table ){
char[] chars=new char[table.length];
for(int i=0;i<table.length;i++){
chars[table[i] - 1] = TextafterPermutation.charAt(i);
}
return new String(chars);
}

Related

code for generating none repeating random numbers. Looks fine to me but when i run it gives me the same number

import java.util.Random;
public class Practice_assignment {
public static void main(String[] args){
int[] winning_numbers = {0,0,0,0,0,0,0,0,0,0} ;
//The i++ for the first loop is in the second loop. I was trying to ensure it only goes to
the next value of the loop once a unique value has been gotten.
for (int i=0; i<10;){
int max = 99;
int min = 1;
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
for (int j=0;j<=i;j++){
if (j<i && winning_numbers[j]==randomNum){
break;
}
else if (j==i && i<10){
winning_numbers[i] = randomNum;
System.out.println(winning_numbers[i]+" ");
i++;
}
}
}
}
}
If I understood correctly what you are trying to achieve, I think you could use something like this:
public class RandomNumbers {
public static void main(String[] args) {
int[] winning_numbers = {0,0,0,0,0,0,0,0,0,0} ;
Random random = new Random();
for(int i = 0; i < winning_numbers.length; i++) {
OptionalInt generatedInt = random.ints(1, 0, 100).findFirst(); // generates a stream of 1 number between 0 and 99 and gets the first (and only) one generated
while (contains(winning_numbers, generatedInt)) {
generatedInt = random.ints(1, 0, 100).findFirst(); // while the generated number is already in the array, generate a new one
}
winning_numbers[i] = generatedInt.getAsInt();
}
System.out.println(Arrays.toString(winning_numbers));
}
// this method will check if the given array already contains the generated int
private static boolean contains(int[] arr, OptionalInt generatedInt) {
return Arrays.stream(arr).anyMatch(number -> generatedInt.getAsInt() == number);
}
}
I ran it a couple of times and here are some outputs I generated with this code:
[52, 54, 21, 62, 47, 13, 94, 36, 82, 25]
[35, 37, 16, 81, 22, 71, 17, 94, 56, 8]
[51, 50, 80, 62, 18, 88, 1, 53, 44, 79]
[16, 95, 18, 66, 31, 4, 1, 55, 52, 26]
[4, 11, 65, 68, 22, 76, 95, 67, 35, 92]
[49, 87, 34, 88, 71, 57, 12, 76, 70, 78]
It appears you want to generate an array of winning_numbers. Here is one ways to do it.
create a helper method to look for duplicate numbers and return true if a duplicate is found.
then iterate over the array checking for the current random number and adding it if unique.
note that min, max, and rand should be initialized outside the loop.
Random rand = new Random();
int[] winning_nummbers = new int[10];
int max = 99;
int min = 1;
for (int i = 0; i < 10;) {
int randomNum = rand.nextInt((max - min) + 1) + min;
// if does not contain a duplicate, then assign
if (!contains(winning_numbers, randomNum)) {
winning_numbers[i++] = randomNum;
}
}
System.out.println(Arrays.toString(winning_numbers));
Prints something like this.
[46, 91, 5, 2, 42, 58, 74, 24, 53, 36]
The helper method.
public static boolean contains(int[] array, int v) {
for (int i = 0; i < array.length; i++) {
if (array[i] == v) {
return true;
}
}
return false;
}
If you want to use streams you can do it like so using a Random instance.
stream values form min to max inclusive.
drop duplicates with distinct
limit(10) limits to 10 values.
put them in an array
int[] winning_numbers = rand.ints(min,max+1)
.distinct()
.limit(10)
.toArray();

using a java switch stament to determine what method to call and repeatedly calling that method

I'm writing a java program where the user can select a sorting algorithm from a list and specify the size of an array to be sorted. The program then generates an array of the specified size filled with random integers and uses a switch statement with a case for each sorting algorithm to call the method for the user's chosen algorithm using the generated array as a parameter.
I want to update my code to allow the user to specify how many arrays are to be sorted with their chosen algorithm. I want to use a for loop to randomly generate and sort the arrays however this doesn't seem ideal because I would have to either:
Place the switch block inside the for loop and check it every loop, even though the same sorting algorithm will be used each time.
Place a for loop in each case within the switch block and have a lot of repeated code in the form of for loops.
Is there a better implementation for this than using switch cases and for loops?
Define an interface (perhaps even a functional interface) named Sorter that has a method
int [] sort( final int [] values )
or
var sort( final int [] values )
if you sort the array in-place.
Implement that interface for each sorting algorithm.
Then you can have a variable Sorter sorter in your program that holds the implementation; it will be initialised in your switch/case statement, based on the user selection.
In your for loop, you will call sorter.sort() for each array to sort.
You can even avoid the switch/case statement by creating a Map<String,Sorter> data structure that is initialised with the name of the sort algorithm as the key and instances of the implementation of Sorter as the value. If Sorter is a functional interface, you can just assign a reference to the respective sort() methods to the Map.
However, this is known as the Strategy pattern …
I decided to try throwing together an example of how you could go about this based off of tquadrat's idea of using a functional interface. I hope it helps!
import java.util.ArrayList;
import java.util.Random;
public class Sorting {
#FunctionalInterface
interface SortType {
Integer[] sort(Integer[] array);
}
public static void main(String[] args) {
int numArrays = 5;
int numValues = 10;
ArrayList<Integer[]> unsortedArrays = generateArrays(numArrays, numValues);
System.out.println("Unsorted:");
print(unsortedArrays);
ArrayList<Integer[]> sortedArrays = sortArrays(unsortedArrays, Sorting::bubbleSort);
System.out.println("\nSorted:");
print(sortedArrays);
}
//Put together random values
private static ArrayList<Integer[]> generateArrays(int numArrays, int numValues) {
ArrayList<Integer[]> unsortedArrays = new ArrayList<>();
Random rand = new Random();
for (int i = 0; i < numArrays; i++) {
Integer[] array = new Integer[numValues];
for (int j = 0; j < numValues; j++) {
array[j] = rand.nextInt(100);
}
unsortedArrays.add(array);
}
return unsortedArrays;
}
//Loop through using the given sorting method on each array
private static ArrayList<Integer[]> sortArrays(ArrayList<Integer[]> arrays, SortType sortType) {
ArrayList<Integer[]> sortedArrays = new ArrayList<>();
for (Integer[] array : arrays) {
sortedArrays.add(sortType.sort(array));
}
return sortedArrays;
}
//Example sort to use with parameters and return matching the interface
private static Integer[] bubbleSort(Integer[] array) {
int n = array.length;
for (int i = 0; i < n - 1; i++)
for (int j = 0; j < n - i - 1; j++)
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
return array;
}
//Method to print the results
private static void print(ArrayList<Integer[]> arrays) {
for (Integer[] array : arrays) {
for (Integer i : array)
System.out.print(i + ", ");
System.out.println();
}
}
}
Sample output:
Unsorted:
67, 54, 83, 67, 62, 96, 6, 24, 66, 19,
3, 37, 45, 36, 81, 45, 5, 46, 5, 84,
10, 8, 95, 50, 82, 38, 36, 18, 80, 98,
52, 27, 18, 17, 77, 51, 18, 72, 55, 76,
79, 84, 92, 85, 61, 74, 64, 29, 95, 64,
Sorted:
6, 19, 24, 54, 62, 66, 67, 67, 83, 96,
3, 5, 5, 36, 37, 45, 45, 46, 81, 84,
8, 10, 18, 36, 38, 50, 80, 82, 95, 98,
17, 18, 18, 27, 51, 52, 55, 72, 76, 77,
29, 61, 64, 64, 74, 79, 84, 85, 92, 95,

Copying two arrays into one array

The question is to write a program which takes two arrays of 10 integers each, a and b. c is an array with 20 integers. The program should put array a and b into the array c, the first 10 integers of c from array a, the latter 10 from b. Then the program should display c. This is the code i have so far. It prints the values from arrayA into arrayC but i dont know how to print the values from arrayB into arrayC without overriding the information already in arrayC (arrayB).
public class questionTwo
{
public static void main(String[] args)
{
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [20];
for (int i = 0; i < arrayA.length; i++)
arrayC[i] = arrayA[i];
for (int i = 0; i < arrayB.length; i++)
{
int element = 9;
arrayC[element] = arrayB[i];
element++;
}
System.out.println("The values of ArrayC are: ");
for(int val : arrayC)
{
System.out.println(val);
}
}
}
Before explaining how you might fix your current code, I would first suggest you create arrayC using the lengths of arrayA and arrayB (here that has the same practical result, but it has the advantage that you can add more elements to arrayA or arrayB without modifying the code). Next, in real code, I would use System.arraycopy to perform the copies. And use Arrays.toString(int[]) for printing. Like,
int[] arrayA = { 31, 14, 5, 12, 50, 80, 100, 29, 58, 57 };
int[] arrayB = { 9, 13, 156, 78, 36, 46, 86, 98, 63, 2 };
int[] arrayC = new int[arrayA.length + arrayB.length];
System.arraycopy(arrayA, 0, arrayC, 0, arrayA.length);
System.arraycopy(arrayB, 0, arrayC, arrayA.length, arrayB.length);
System.out.println(Arrays.toString(arrayC));
As for your original code, use arrayA.length and i to get the correct offset. Like,
int[] arrayC = new int[arrayA.length + arrayB.length];
for (int i = 0; i < arrayA.length; i++) {
arrayC[i] = arrayA[i];
}
for (int i = 0; i < arrayB.length; i++) {
arrayC[i + arrayA.length] = arrayB[i];
}
You were really close! Your second loop initializes element to 9 every time, while you should only assign it to 10 once at the beginning:
int element = 10;
for (int i = 0; i < arrayB.length; i++)
{
arrayC[element] = arrayB[i];
element++;
}
Make your function dynamic while you need to add more item into your arrays. I did not test yet, but I hope it work.
public class questionTwo
{
public static void main(String[] args)
{
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [arrayA.length + arrayB.length];
for (int i = 0; i < arrayA.length; i++)
arrayC[i] = arrayA[i];
int element = arrayA.length;
for (int i = 0; i < arrayB.length; i++)
{
arrayC[element+i] = arrayB[i];
}
System.out.println("The values of ArrayC are: ");
for(int val : arrayC)
{
System.out.println(val);
}
}
}
The second loop is wrong. You can use the follow code:
int [] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int [] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int [] arrayC = new int [20];
System.arraycopy(arrayA, 0, arrayC, 0, arrayA.length);
System.arraycopy(arrayB, 0, arrayC, arrayA.length, arrayB.length);
System.out.println("The values of ArrayC are: ");
for(int val : arrayC) {
System.out.println(val);
}
Your second loop is incorrect because you are setting element to 9 within the loop each time; thus, its value is always reset upon beginning the next iteration. You could move it outside the loop to achieve the result you're looking for. Also, I'd recommend constructing arrayC based on the lengths of arrayA and arrayB, that way you can combine array's of any length.
In addition, I'd also recommend moving the code to combine the arrays to a method to keep things clean and reusable for future endeavors.
public class questionTwo {
private static int[] combineArrays(int[] arrayA, int[] arrayB) {
int[] arrayC = new int[arrayA.length + arrayB.length];
int idx = 0;
for (int x : arrayA) {
arrayC[idx] = x;
idx++;
}
for (int x : arrayB) {
arrayC[idx] = x;
idx++;
}
return arrayC;
}
public static void main(String[] args) {
int[] arrayA = {31, 14, 5, 12, 50, 80, 100, 29, 58, 57};
int[] arrayB = {9, 13, 156, 78, 36, 46, 86, 98, 63, 2};
int[] arrayC = combineArrays(arrayA, arrayB);
System.out.println("The values of ArrayC are: ");
for(int val : arrayC) {
System.out.println(val);
}
}
}
Also, it is often considered a poor practice to use Java's primitive arrays. Check out List and related objects for more flexible and full-featured options.

How to extract these integer values from ArrayList<String> [duplicate]

This question already has answers here:
Cast Double to Integer in Java
(19 answers)
Closed 7 years ago.
I am having a ArrayList<String> abc in which I am getting this value [64.3, 25.1, 44.3, 34.2, 6.4, 48.5, 35.5, 59.5, 54.6, 26.6, 11.2, 50.3, 25.1]
Now I want to extract the integer values from it such as 64,25,44,34,6,48,35,59,54,26,11,50,25 and put these values in an integer array int[] cab
How can I get this? How to remove the decimal and after decimal values from it?
Here are three different (but similar) ways of doing it, depending on Java version and/or preferences:
ArrayList<String> abc = new ArrayList<>(Arrays.asList(
"64.3", "25.1", "44.3", "34.2", "6.4", "48.5", "35.5",
"59.5", "54.6", "26.6", "11.2", "50.3", "25.1" ));
System.out.println("abc = " + abc);
// Loop (all Java versions)
int[] cab1 = new int[abc.size()];
for (int i = 0; i < cab1.length; i++)
cab1[i] = (int)Double.parseDouble(abc.get(i));
System.out.println("cab1 = " + Arrays.toString(cab1));
// Java 8 stream with lambda expression
int[] cab2 = abc.stream()
.mapToInt(v -> (int)Double.parseDouble(v))
.toArray();
System.out.println("cab2 = " + Arrays.toString(cab2));
// Java 8 stream with method references
int[] cab3 = abc.stream()
.map(Double::valueOf)
.mapToInt(Double::intValue)
.toArray();
System.out.println("cab3 = " + Arrays.toString(cab3));
Output
abc = [64.3, 25.1, 44.3, 34.2, 6.4, 48.5, 35.5, 59.5, 54.6, 26.6, 11.2, 50.3, 25.1]
cab1 = [64, 25, 44, 34, 6, 48, 35, 59, 54, 26, 11, 50, 25]
cab2 = [64, 25, 44, 34, 6, 48, 35, 59, 54, 26, 11, 50, 25]
cab3 = [64, 25, 44, 34, 6, 48, 35, 59, 54, 26, 11, 50, 25]
Try This :
Integer cab[] = new Integer[abc.size()];
cab= abc.toArray(cab);
//iterating array
for (Integer cabs: cab) {
System.out.println("cab= " + cabs);
}
Simply iterate:
int[] cab = new int[abc.size()];
for(int i = 0; i < cab.length; i++){
cab[i] = (int)Float.parseFloat(abc.get(i));
}
In Java 8:
int[] cab = abc.stream()
.map(Double::valueOf)
.mapToInt(Double::intValue)
.toArray();
use this code
Iterator itr = al.iterator();
while(itr.hasNext()) {
String s1=itr.next().toString();
Double d=new Double(s1);
int s2=d.intValue();
System.out.print(s2 + " ");
}
string to double
double to int
for(int i = 0 ; i < abc.size(); ++i) {
tmp = Double.parseDouble(abc.get(i));
cab[i] = (int)tmp;
System.out.println(cab[i]);
}
ArrayList<Integer> newList = new ArrayList<Integer>(stringsList.size());
for (String myInt : strings){
int intVal = (int)Double.parseDouble(myInt);
newList.add(intVal);
}
where stringsList is your Arraylist

Java - How do I convert a string of letters into an array with the corresponding numerical values?

How can I easily convert the following string into an array of integers with the corresponding numerical values (i.e. a = 0, b = 1, c = 2, etc):
String plaintext = "sallywenttotheseashoretocollectseashellsxx";
Well, your question as stated is poorly defined, but here's what you could do:
char[] chars = text.toCharArray();
int[] results = new int[text.length()];
for(int i = 0; i < text.length(); i++) {
//your poorly defined conversion
results[i] = someOperation(chars[i])
}
.
.
// a best guess at what this function would do
private static int someOperation(char c) {
return (c - 'a');
}
If the letter a maps to 0, what does the letter A map to?
The following code works for lower case only:
int[] string_to_numbers = new int[s.length()];
for(int i=0; i<s.length(); i++){
string_to_numbers[i] = s.charAt(i)-'a';
}
We can start with the identity you've given 'a' = 0, that means we can just subtract 'a' from any given character. That is something like,
String plaintext = "sallywenttotheseashoretocollectseashellsxx";
char[] letterArray = plaintext.toCharArray();
int[] array = new int[letterArray.length];
for (int i = 0; i < letterArray.length; i++) {
array[i] = letterArray[i] - 'a';
}
System.out.println(Arrays.toString(array));
Output is (formatted for this post)
[18, 0, 11, 11, 24, 22, 4, 13, 19, 19, 14, 19, 7, 4, 18, 4, 0, 18, 7, 14, 17, 4,
19, 14, 2, 14, 11, 11, 4, 2, 19, 18, 4, 0, 18, 7, 4, 11, 11, 18, 23, 23]
You can deduct the character 'a' from the character itself so that would give 0 for 'a', 1 for 'b' etc.
int[] digits = new int[plaintext.length()];
for(int i = 0; i < digits.length; i++) {
digits[i] = plaintext.charAt(i) - 'a';
}
NOTE: this will only work for lowercase letters
String plaintext = "sallywenttotheseashoretocollectseashellsxx";
int arr[] = new int[plaintext.length()];
for(int i=0;i<plaintext.length();i++){
arr[i]= plaintext.charAt(i)-96;
}
you can convert your text to lowercase, in case it may also have uppercase letters
Just -a or ASCII value of a(97). You can try this
public class ASCII {
public static void main(String[] args) {
String plaintext = "sallywenttotheseashoretocollectseashellsxx";
int a_code[];
a_code = new int[plaintext.length()];
for(int i = 0; i < plaintext.length(); i++){
a_code[i] = plaintext.charAt(i) - 'a'; //plaintext.charAt(i) - 97;
}
for(int i = 0; i < plaintext.length(); i++){
System.out.println(a_code[i]);
}
}
}

Categories