I use simple method to change string values without changing original length of string.then back convert change the text back into pure string(into Original text).
My code :
String someText = "abcdefgHIJKLMN";
char[] data = someText.toCharArray();
int LEN = someText.length();
char[] datas = new char[LEN];
System.out.println("Original Text ("+String.valueOf(LEN)+"): "+someText);
for (int i = 0; i < LEN; i++) {
data[i] = Character.valueOf((char) i);
System.out.println(String.valueOf(i) + " = " + String.valueOf((char) i));
}
System.out.println("Add 10 into each charactor : "); // ex a =1 , a+10 : now it's 'k'
for (int i = 0; i < LEN; i++) {
char c = Character.valueOf((char) (Character.getNumericValue(Character.valueOf(data[i])) + 10));
datas[i] = c;
System.out.print(String.valueOf(c));
}
System.out.println("Subtract 10 from each charactor : ");// ex k =11 , k-10 : now it should be 'a'
for (int i = 0; i < LEN; i++) {
char c = (char) (Character.getNumericValue(Character.valueOf(datas[i])) - 10);
System.out.print(String.valueOf(c));
}
But after adding and subtracting that loops dose not display anything.
If there is any solution to achieve this type of things without changing original length of text?
This is the thing I want to do:
Let say character value of a is 97 then we add 10 into it:(97+10) = 107 now it's not a it's should be different letter such as k because 107 character value is :K
I think the problem is in line 8:
data[i] = Character.valueOf((char) i);
When i = 0, data[i] is not 'a'. 'a' has a value of 97 (hex 61):
http://www.utf8-chartable.de/
Moreover you can add chars using '+' but the result of '+' operator is integer, so you only have to cast it to char - ie.
char c = (char) (data[i] + 10);.
Also in your loops you used print instead of println, that's why the output was not so clear. Try the code below and see if it works out for you.
String someText = "abcdefgHIJKLMN";
char[] data = someText.toCharArray();
int LEN = someText.length();
char[] datas = new char[LEN];
System.out.println("Original Text ("+String.valueOf(LEN)+"): "+someText);
for (int i = 0; i < LEN; i++) {
System.out.println(String.valueOf(i) + " = " + data[i]);
}
System.out.println("Add 10 into each charactor : "); // ex a =1 , a+10 : now it's 'k'
for (int i = 0; i < LEN; i++) {
char c = (char) (data[i] + 10);
datas[i] = c;
System.out.println(String.valueOf(c));
}
System.out.println("Subtract 10 from each charactor : ");// ex k =11 , k-10 : now it should be 'a'
for (int i = 0; i < LEN; i++) {
char c = (char) (datas[i] - 10);
System.out.println(String.valueOf(c));
}
Related
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.
So I have a program in java that takes a string from user input, sorts it, finds the frequencies, and prints it in alphabetical order. My only issue is that it also prints duplicates. So, if the letter d appeared three times in a string, it would print like this:
d freq: 3
d freq: 3
d freq: 3
For this project, I am not allowed to use any built-in java sorting functions (hashmaps included). Any suggestions on how to stop this? Here's my code. Thank you!
char[] charArray = userSort.toCharArray();
char tempChar;
for (int i = 0; i < charArray.length; i++) {
for (int j = 0; j < charArray.length; j++) {
if (charArray[i] < charArray[j]) {
tempChar = charArray[i];
charArray[i] = charArray[j];
charArray[j] = tempChar;
}
}
}
String sortedString = "";
for (int i = 0; i < charArray.length; i++) {
userSort += charArray[i];
}
System.out.println(sortedString + "\n");
int counter;
sortedString = "";
for (int i = 0; i < charArray.length; i++) {
counter = 0;
for (int j = 0; j < charArray.length; j++) {
if (charArray[i] == charArray[j]) {
counter++;
}
}
if (!sortedString.contains("Char: " + charArray[i])) {
if (sortedString.equals("")) {
sortedString += " " + charArray[i] + " freq: " + counter + "\n";
} else {
sortedString += " " + charArray[i] + " freq: " + counter + "\n";
}
}
}
System.out.println(sortedString);
Make sure that i != 0.
Compare charArray [i] to charArray [i-1].
If they're not equal, then print out the result.
You can use a TreeMap<Character, Integer> to keep sorted character order and for counting letter frequencies.
Map<Character, Integer> freqs = new TreeMap<>();
for (char c : charArray.length) {
freqs.put(c, 1+freqs.getOrDefault(c, 0));
}
You also don't need to sort the input string. (Especially not using bubble sort). Iterating the characters and adding/updating to the map will create the order.
What you need to do is a Bucket Sort
In brief, create a int array of length 26, which represent 26 characters (Let's call this the "counter array"
Loop through your string. For each character encountered, increment the corresponding int in the counter array.
After looping through the input string, the counter array will contains the number of occurrence for each of 26 characters
The rest should be straight-forward I believe, which you just need to loop thru the counter array and print corresponding output
Spoiler ahead: sample code. Don't read if you haven't tried to write your code
String input = "The quick brown fox jumps over a lazy dog";
int[] counter = new int[26];
for (char c : input.toLowerCase().toCharArray()) {
if (c >= 'a' && c <= 'z') {
counter[c-'a']++;
}
}
for (int i = 0; i < counter.length; ++i) {
System.out.println("" + (char)('a' + i) + " occurs " + counter[i] + " times");
}
Solution: updated without hashmap and sorting:
Algo:
1.Create temp array of 26 alphabet and put frequency count ..i.e
0-> a,
1-> b....
2.Iterate array to print the result
public static void countFrequency(){
String user = "Harshal";
user = user.toLowerCase();
char ch[]= user.toCharArray();
int arr[] = new int[26];
for(char c : ch){
arr[c-97]++;
}
for(int k=0;k<26;k++){
if(arr[k]!=0){
int val = k+97;
System.out.println((char)val + " freq: " + arr[k]);
}
}
}
I have the problem when decrypting the text message. Example :
Plaintext : "halo brother"
Ciphertext : "žiÌ=ßOÌÅbO"
Plaintext : "haフo`bメothナメ"
k1 : 33 ->first key
k2 : 125 ->second key
I use ASCII printable & ASCII extended characters set total 224 characters.
Here is my code :
public class Affine {
//encyption method
public static String enkripsi(String pesan, int k1, int k2){
//change text message into array
char[] chars = pesan.toCharArray();
//getting ASCII code from each characters index
int[] ascii = new int[chars.length];
for (int i = 0; i < chars.length; i++) {
ascii[i] = (int) chars[i];
}
//Affine encryption formula
int[] c = new int[ascii.length];
for (int j = 0; j < ascii.length; j++) {
c[j] = ((k1*ascii[j])+k2) % 224 ;
}
//change the decimal (ASCII code) value back to characters
char[] charen = new char[c.length];
for (int i = 0; i < c.length; i++) {
charen[i] = (char)c[i];
}
//change characters to String
String pesan_en = String.valueOf(charen);
return pesan_en;
}
//decryption method
public static String dekripsi(String isipesanMasuk, int k1, int k2){
int j,g;
int[] c;
int[] f = new int [224];
//change text message into array
char[] chars = isipesanMasuk.toCharArray();
//getting ASCII code from each characters index
int[] ascii = new int[chars.length];
for (int i = 0; i < chars.length; i++) {
ascii[i] = (int) chars[i];
}
//getting inverse from encryption formula of Affine
//example 33f = 1 (mod) 224 -> f = (1+(224 * j)) / 5
//g = (33 * f) mod 224
//if g = 1 then stop
for (j = 1; j < 224; j++) {
f[j] = (1 +(224*j)) / k1;
g = (k1*f[j]) % 224 ;
if (g==1) {
break;
}
}
//Affine decrypion formula
c = new int[ascii.length];
for (int k = 0; k < ascii.length; k++) {
c[k] = (f[j]*(ascii[k]-k2)) % 224 ;
}
//change the decimal (ASCII code) value back to characters
char[] charde = new char[c.length];
for (int i = 0; i < c.length; i++) {
charde[i] = (char)c[i];
}
//change characters to String
String pesan_de = String.valueOf(charde);
return pesan_de;
}
}
The decryption formula breaks down if ascii[k]-k2 gives a negative value. To fix that use this:
c[k] = (f[j]*(ascii[k]-k2+224)) % 224;
Some other remarks:
you don't need an array to calculate the inverse of k1, a simple integer variable will do.
The encryption can result in control characters (\u0000 to \u000f and \u007f to \u009f) that might not be transported unaltered across all channels.
I want to convert binary to decimals and characters like this:
11010 --> 1101 + 0(parity bit) -->decimals= 11 --> char ";"
10101 --> 1010 + 1 -->decimals= 5 --> char "5"
.
.
public class stringek {
String bitek = "1101010101001000001000001";
String[] bits;
String four;
char par;
int parity;
String digits;
int n = 0;
int b;
int kurens;
int decimalis;
int digit;
public stringek() {
this.kurens = 0;
bits = new String[200];
for (int i = 0; i < 25; i += 5) {
bits[n] = bitek.substring(i, i + 5);
n++;
}
for (int i = 0; i < n; ++i) {
int j = 0;
four = bits[i].substring(j, j + 4);
for (int p = 0; p < 4; ++p) {
b = Integer.parseInt(four.substring(p));
kurens += b;
}
par = bits[i].charAt(j+4);
//System.out.print(par);
parity = par-'0';
decimalis = Integer.parseInt(four, 2);
digit = decimalis + 48;
if ((kurens + parity) % 2 == 0) {
System.out.println("Binarys: "+four+"-"+par+" = "+"'"+(char)digit+"'"+" Decimalis:"+decimalis+" Parity <INVALID> ");
}
else{
System.out.println("Binarys: "+four+"-"+par+" = "+"'"+(char)digit+"'"+" Decimalis:"+decimalis+" Parity <VALID> ");
}
}
}
}
but my program results this:
Binarys: 1101-0 = '=' Decimalis:13 Parity <INVALID>
Binarys: 1010-1 = ':' Decimalis:10 Parity <VALID>
Binarys: 0010-0 = '2' Decimalis:2 Parity <INVALID>
Binarys: 0001-0 = '1' Decimalis:1 Parity <INVALID>
Binarys: 0000-1 = '0' Decimalis:0 Parity <VALID>
Can anyone help me to resolve? I have to say cause in my case all Parity is VALID, but I don't know why here some Parity is Invalid (I know cause the results from if give me this results, but I want to know how to resolve to be VALID when is valid and INVALID when is really invalid). thanks
public String[] splitStringEvery(String s, int interval) {
int arrayLength = (int) Math.ceil(((s.length() / (double)interval)));
String[] result = new String[arrayLength];
int j = 0;
int lastIndex = result.length - 1;
for (int i = 0; i < lastIndex; i++) {
result[i] = s.substring(j, j + interval);
j += interval;
} //Add the last bit
result[lastIndex] = s.substring(j);
return result;
}
You wouldn't use String.split() or a StringTokenizer
Use a for loop that increments by 5, checking against length of your string
Use String.substring() to extract the 5 character strings.
To compute the length of the target array you need, you'll need to divide your string length by 5. A Better idea is to use a List<String>.
Use the Guava Libraries Splitter object, specifically the fixedLength(...) method which does exactly what you're trying to do.
Splitter splitter = Splitter.fixedLength(5);
Iterable<String> tokens= splitter.split(myVeryLongString);
I am writing a java code for finding element Ex.food for any attribute(attr)Ex.description in XML.
What I have done
I am taking first char of attr as start position and then checking if it equals to "<" .From this point I am looping to ignore white space,tab etc and proceed to append valid char till I find another white space,tab.But this is not working.It is supposed to find the first word after "<" and print that only .But its actually going till the end from the the point it find first char after "<"
Note:I cannot use XML parsers like DOM etc
XML
<breakfast_menu>
<food name="Belgian Waffles" price="$5.95" discount="20"
description="Two" calories="650" />
</breakfast_menu>
for (int k = start_position; k >= 0; k--) {
char testChar = xmlInString.charAt(k);
String temp = Character.toString(testChar);
if ("<".equals(temp)) {
System.out.println(k + "value of k");
for (int j = k + 1; j >= 0; j++) {
char appendChar = xmlInString.charAt(j);
String temp1 = Character.toString(appendChar);
if(!("".equals(temp1))) {
System.out.println(j + " " + appendChar);
}
}
}
}
I made few changes now and its working as expected.i.e giving first word after "<". If you have any suggestion please let me know.
int k, j, l;
for (k = start_position; k >= 0; k--) {
char testChar = xmlInString.charAt(k);
String temp = Character.toString(testChar);
if ("<".equals(temp)) {
break;
}
}
for (j = k + 1; j <= start_position; j++) {
char appendChar = xmlInString.charAt(j);
String temp1 = Character.toString(appendChar);
if (!("".equals(temp1))) {
break;
}
}
for (l = j; l <= start_position; l++) {
char appendChar1 = xmlInString.charAt(l);
String temp2 = Character.toString(appendChar1);
if (" ".equals(temp2)) {
break;
}
}
System.out.println(xmlInString.substring(j, l));
I think this will help
String str = "<food name=\"Belgian Waffles\" price=\"$5.95\" discount=\"20\"\n" ;
String res = str.substring(str.indexOf("<"), str.indexOf(" ", str.indexOf("<") + "<".length()) + " ".length());
System.out.println(res);
output
<food
Your inner while loop for (int j = k + 1; j >= 0; j++) { is broken. The condition j >= 0 doesn't make sense - j only increments so how could it ever be < 0? Instead you should be looking for the next space, tab, etc.
I don't think your solution is going to work, but that is what's wrong with the code you have posted and why it's running off the end.