String word = "ABCD";
StringBuffer str = new StringBuffer (word);
int counter = 0;
for (int ch = 0; ch < word.length(); ch ++)
{
int number = word.charAt(ch)- 'A' + 1;
str.setCharAt(counter, (char) number);
if (ch != word.length ()-1)
str.insert(counter +1, '-');
counter += 2;
}
System.out.println (str);
}
I want my output to be 1-2-3-4, so A = 1 and B= 2.... etc. We can assume that all the input are in upper case. But the my code produce random symbols. So how do I fix the code to produce 1-2-3-4 without re writing the whole thing?
You're only missing the conversion from int back to char. The line
str.setCharAt(counter, (char) number);
should be
str.setCharAt(counter, (char) ('0' + number));
Related
My attempt at using a Caeser Cipher is failing on capital letters has incorrect results.
input: All-convoYs-9-be:Alert1. and rotation factor is 200
Correct output: Epp-gsrzsCw-3-fi:Epivx5.
My result:
_pp-gsrzs]w-3-fi:_pivx5.
String rotationalCipher(String input, int rotationFactor) {
StringBuilder sb = new StringBuilder();
char[] chars = input.toCharArray();
for(char c : chars){
if(Character.isLetter(c)){
int currentPos = c - 'a';
int newPos = (currentPos + rotationFactor) % 26;
char newCharacter = (char) ('a' + newPos);
sb.append(newCharacter);
}else if(Character.isDigit(c)){
String y = Character.toString(c);
int x = Integer.parseInt(translateNumber(y,rotationFactor));
sb.append(x);
}else {
sb.append(c);
}
}
return sb.toString();
}
String translateNumber(String oldNumber, int rotationFactor){
Integer n = Integer.parseInt(oldNumber);
int newNumber = n + rotationFactor;
if(newNumber > 10){
newNumber = newNumber % 10;
}
return String.valueOf(newNumber);
}
int verifyRotationFactor(int rotationFactor){
int max = 26;
int div = rotationFactor / max;
if(div > 1){
return div;
}
return rotationFactor;
}
I'm very new to this, not sure what I need to fix.
It seems like ASCII related problem to me. You should shift position of letter in an array that contains letters. In your way it shifts letters by ASCII order.
So
It finds C and replace it with "]"
It finds E and replace it with "_"
If it would find B, the program will return "\" eventually.
BECAUSE THERE IS NON-ALPHANUMERIC VALUES BETWEEN LETTERS IN ASCII
TABLE.
more info: https://www.fileformat.info/info/charset/UTF-16/list.html
In order to make cipher work better, you need an array to loop inside.
I'm trying to solve Caesar's Cipher in Java but there's a twist to it. The input string has alphanumeric values and I am unable to solve. Here's what I've attempted so far:
String rotationalCipher(String input, int rotationFactor) {
// Write your code here
StringBuilder sb = new StringBuilder();
for(int i = 0; i < input.length(); i++) {
if(Character.isLowerCase(input.charAt(i))) {
char ch = (char)(((int)input.charAt(i) + rotationFactor - 97) % 26 + 97);
} else if (Character.isUpperCase(input.charAt(i))) {
char ch = (char)(((int)input.charAt(i) + rotationFactor - 65) % 26 + 65);
sb.append(ch);
} else {
char ch = (char)(((int)input.charAt(i) + rotationFactor - 48) % 10 + 48);
sb.append(ch);
}
}
return sb.toString();
}
What I'm trying to do is evaluate each case using its ASCII values but I don't seem to get the desired output. Am I using ASCII wrong? Thanks for your help!
Sample input/output:
input = Zebra-493?
rotationFactor = 3
output = Cheud-726?
You have two major problems.
You did not update StringBuilder with an append for lowercase transitions.
You need to handle digits specially using isDigit just like upper and lower case so that you can then ignore characters like - and ?
A couple of suggestions.
just assign ch when you first enter the loop and then use it throughout the loop. No need to keep typing in all the input stuff.
only append ch to the StringBuilder once near the end when you exit the if/else blocks.
Instead of numbers like 97 and 65 use 'a' and 'A'. Less likely to make mistakes that way.
Once you make those changes, your code works just fine.
Below code works for me-
String rotationalCipher(String input, int rotationFactor) {
// Write your code here
StringBuffer sb = new StringBuffer();
for (int i = 0; i < input.length(); i++) {
char x = input.charAt(i);
if (Character.isLowerCase(x)) {
char ch = (char) ((x + rotationFactor - 97) % 26 + 97);
sb.append(ch);
} else if (Character.isUpperCase(x)) {
char ch = (char) ((x + rotationFactor - 65) % 26 + 65);
sb.append(ch);
} else if (Character.isDigit(x)) {
char ch = (char) ((x + rotationFactor - 48) % 10 + 48);
sb.append(ch);
} else {
sb.append(x);
}
}
return sb.toString();
}
String rotationalCipher(String input, int rotationFactor) {
String output = "";
for(char a: input.toCharArray()){
if(Character.isAlphabetic(a)){
char startLetter = Character.isUpperCase(a) ? 'A' : 'a';
output += (char) ((a- startLetter + rotationFactor) % 26 + startLetter);
}
else if(Character.isDigit(a)){
output += (char) ((a + rotationFactor - 48) % 10 + 48);
}
else{
output += a;
}
}
return output;}
I'm trying to count the number of occurrences of letters that are in string. The code that I have written technically does what I want, but not the way I want to do it. For example, if I input "Hello World", I want my code to return "a=0 b=0 c=0 d=0 e=1 etc...." with the code I have written it returns "H=1, e=1, l=2 etc...."
Also how would I make sure that it is not case sensitive and it doesn't count spaces.
Code:
import java.util.Scanner;
public class Sequence {
private static Scanner scan = null;
public static void main(String[] args) {
scan = new Scanner(System.in);
String str = null;
System.out.print("Type text: ");
str = scan.nextLine();
int[] count = new int[255];
int length = str.length();
for (int i = 0; i < length; i++)
{
count[str.charAt(i)]++;
}
char[] ch = new char[str.length()];
for (int i = 0; i < length; i++)
{
ch[i] = str.charAt(i);
int find = 0;
for (int j = 0; j <= i; j++)
{
if (str.charAt(i) == ch[j])
find++;
}
if (find == 1)
{
System.out.print(str.charAt(i) + "=" + count[str.charAt(i)] + " ");
}
}
}
}
As I hinted in my original comment you only need an array of 26 int(s) because there are only 26 letters in the alphabet. Before I share the code, it is important to note that Java char is an integral type (and, for example, 'a' + 1 == 'b'). That property is important, because it allows you to determine the correct offset in an array (especially if you force the input to lower case). Something like,
Scanner scan = new Scanner(System.in);
System.out.print("Type text: ");
String str = scan.nextLine();
int[] count = new int[26];
for (int i = 0; i < str.length(); i++) {
char ch = Character.toLowerCase(str.charAt(i)); // not case sensitive
if (ch >= 'a' && ch <= 'z') { // don't count "spaces" (or anything non-letter)
count[ch - 'a']++; // as 'a' + 1 == 'b', so 'b' - 'a' == 1
}
}
for (int i = 0; i < count.length; i++) {
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
}
System.out.println();
If you really want to see all of the letters that have counts of zero (seems pointless to me), change
if (count[i] != 0) {
System.out.printf("%c=%d ", 'a' + i, count[i]);
}
to remove the if and just
System.out.printf("%c=%d ", 'a' + i, count[i]);
Change str = scan.nextLine(); to str = scan.nextLine().toLowerCase().replaceAll("\\s+","");
.toLowerCase() is a method which makes every char in the string lowercase.
.replaceAll() is a method which replaces one char with another. In this case, it replaces whitespaces with nothing.
Take as input S, a string. Write a function that replaces every odd character with the character having just higher ASCII code and every even character with the character having just lower ASCII code. Print the value returned.
package assignments;
import java.util.Scanner;
public class strings_odd_even_char {
static Scanner scn = new Scanner(System.in);
public static void main(String[] args) {
String str = scn.nextLine();
for (int i = 0; i < str.length(); i = i + 2) {
char ch = str.charAt(i);
ch = (char)((ch + 1));
System.out.println(ch);
}
for (int j = 1; j < str.length(); j = j + 2) {
char ch = str.charAt(j);
ch = (char)((ch - 1));
System.out.print(ch);
}
}
}
The problem with my code is that it is first printing the values for all the odd characters and then for even characters but what I want is that they get printed in proper sequence like for input --> abcg , the output should be --> badf .
I'd hold the "incremenet" value in a variable and alternate it between +1 and -1 as I go voer the characters:
private static String change(String s) {
StringBuilder sb = new StringBuilder(s.length());
int increment = 1;
for (int i = 0; i < s.length(); ++i) {
sb.append((char)(s.charAt(i) + increment));
increment *= -1;
}
return sb.toString();
}
Just use one loop that handles both characters:
for (int i = 0; i < str.length(); i = i + 2) {
char ch = str.charAt(i);
ch = (char) (ch + 1);
System.out.print(ch);
if (i + 1 < str.length()) {
ch = str.charAt(i + 1);
ch = (char) (ch - 1);
System.out.print(ch);
}
}
You only need to iterate one time but do different operation (char+1) or (char-1) depending on the i:
public static void main(String[] args) {
String str = scn.nextLine();
for(int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i % 2 == 0) { // even
ch += 1;
} else { // odd
ch -= 1;
}
System.out.print(ch);
}
}
You are using two loops, but you only need one. You can use the % operator to tell if i is even or odd, and then either subtract or add accordingly:
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i % 2 == 0) {
ch = (char)((ch + 1));
System.out.println(ch);
} else {
ch = (char)((ch - 1));
System.out.print(ch);
}
}
You can do it in one for loop, to do that you will need to check whether the current index is even or odd. if current index is even you will increment char and print, if it is odd you will decrement char and print. to check if even or odd using % operator
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
if(i%2 == 0) {
ch = ch + 1;
System.out.println(ch);
continue;
}
ch = ch - 1;
System.out.println(ch);
}
I hope this isn't too much of a stupid question, I have looked on 5 different pages of Google results but haven't been able to find anything on this.
What I need to do is convert a string that contains all Hex characters into ASCII for example
String fileName =
75546f7272656e745c436f6d706c657465645c6e667375635f6f73745f62795f6d757374616e675c50656e64756c756d2d392c303030204d696c65732e6d7033006d7033006d7033004472756d202620426173730050656e64756c756d00496e2053696c69636f00496e2053696c69636f2a3b2a0050656e64756c756d0050656e64756c756d496e2053696c69636f303038004472756d2026204261737350656e64756c756d496e2053696c69636f30303800392c303030204d696c6573203c4d757374616e673e50656e64756c756d496e2053696c69636f3030380050656e64756c756d50656e64756c756d496e2053696c69636f303038004d50330000
Every way I have seen makes it seems like you have to put it into an array first. Is there no way to loop through each two and convert them?
Just use a for loop to go through each couple of characters in the string, convert them to a character and then whack the character on the end of a string builder:
String hex = "75546f7272656e745c436f6d706c657465645c6e667375635f6f73745f62795f6d757374616e675c50656e64756c756d2d392c303030204d696c65732e6d7033006d7033006d7033004472756d202620426173730050656e64756c756d00496e2053696c69636f00496e2053696c69636f2a3b2a0050656e64756c756d0050656e64756c756d496e2053696c69636f303038004472756d2026204261737350656e64756c756d496e2053696c69636f30303800392c303030204d696c6573203c4d757374616e673e50656e64756c756d496e2053696c69636f3030380050656e64756c756d50656e64756c756d496e2053696c69636f303038004d50330000";
StringBuilder output = new StringBuilder();
for (int i = 0; i < hex.length(); i+=2) {
String str = hex.substring(i, i+2);
output.append((char)Integer.parseInt(str, 16));
}
System.out.println(output);
Or (Java 8+) if you're feeling particularly uncouth, use the infamous "fixed width string split" hack to enable you to do a one-liner with streams instead:
System.out.println(Arrays
.stream(hex.split("(?<=\\G..)")) //https://stackoverflow.com/questions/2297347/splitting-a-string-at-every-n-th-character
.map(s -> Character.toString((char)Integer.parseInt(s, 16)))
.collect(Collectors.joining()));
Either way, this gives a few lines starting with the following:
uTorrent\Completed\nfsuc_ost_by_mustang\Pendulum-9,000 Miles.mp3
Hmmm... :-)
Easiest way to do it with javax.xml.bind.DatatypeConverter:
String hex = "75546f7272656e745c436f6d706c657465645c6e667375635f6f73745f62795f6d757374616e675c50656e64756c756d2d392c303030204d696c65732e6d7033006d7033006d7033004472756d202620426173730050656e64756c756d00496e2053696c69636f00496e2053696c69636f2a3b2a0050656e64756c756d0050656e64756c756d496e2053696c69636f303038004472756d2026204261737350656e64756c756d496e2053696c69636f30303800392c303030204d696c6573203c4d757374616e673e50656e64756c756d496e2053696c69636f3030380050656e64756c756d50656e64756c756d496e2053696c69636f303038004d50330000";
byte[] s = DatatypeConverter.parseHexBinary(hex);
System.out.println(new String(s));
String hexToAscii(String s) {
int n = s.length();
StringBuilder sb = new StringBuilder(n / 2);
for (int i = 0; i < n; i += 2) {
char a = s.charAt(i);
char b = s.charAt(i + 1);
sb.append((char) ((hexToInt(a) << 4) | hexToInt(b)));
}
return sb.toString();
}
private static int hexToInt(char ch) {
if ('a' <= ch && ch <= 'f') { return ch - 'a' + 10; }
if ('A' <= ch && ch <= 'F') { return ch - 'A' + 10; }
if ('0' <= ch && ch <= '9') { return ch - '0'; }
throw new IllegalArgumentException(String.valueOf(ch));
}
Check out Convert a string representation of a hex dump to a byte array using Java?
Disregarding encoding, etc. you can do new String (hexStringToByteArray("75546..."));
So as I understand it, you need to pull out successive pairs of hex digits, then decode that 2-digit hex number and take the corresponding char:
String s = "...";
StringBuilder sb = new StringBuilder(s.length() / 2);
for (int i = 0; i < s.length(); i+=2) {
String hex = "" + s.charAt(i) + s.charAt(i+1);
int ival = Integer.parseInt(hex, 16);
sb.append((char) ival);
}
String string = sb.toString();
//%%%%%%%%%%%%%%%%%%%%%% HEX to ASCII %%%%%%%%%%%%%%%%%%%%%%
public String convertHexToString(String hex){
String ascii="";
String str;
// Convert hex string to "even" length
int rmd,length;
length=hex.length();
rmd =length % 2;
if(rmd==1)
hex = "0"+hex;
// split into two characters
for( int i=0; i<hex.length()-1; i+=2 ){
//split the hex into pairs
String pair = hex.substring(i, (i + 2));
//convert hex to decimal
int dec = Integer.parseInt(pair, 16);
str=CheckCode(dec);
ascii=ascii+" "+str;
}
return ascii;
}
public String CheckCode(int dec){
String str;
//convert the decimal to character
str = Character.toString((char) dec);
if(dec<32 || dec>126 && dec<161)
str="n/a";
return str;
}
To this case, I have a hexadecimal data format into an int array and I want to convert them on String.
int[] encodeHex = new int[] { 0x48, 0x65, 0x6c, 0x6c, 0x6f }; // Hello encode
for (int i = 0; i < encodeHex.length; i++) {
System.out.print((char) (encodeHex[i]));
}