Adding/Subtracting big number to and from a character - java

For case #1, adding 2 to 'a' gives us 'c'.
How can I write a program so that adding 2 to 'z' gives 'b' as an output and subtracting 3 from 'a' gives 'x' as an output?
In other words, I want only alphabet character as an output. No matter how big number you are adding or subtracting to and from the character, I always expect the output between a and z inclusive.
case #1
public void addNumberToCharacter{
char character = 'a' + 2;
System.out.println(character); // 'c'
}
case #2
public void addNumberToCharacter{
char character = 'z' + 2;
System.out.println(character); // 'b'
}
case #3
public void addNumberToCharacter{
char character = 'a' - 3;
System.out.println(character); // 'x'
}

To handle two cases you might also require:
uppercase and lowercase;
adding/subtracting number whose absolute value is bigger than 26;
And here is the method you can refer to:
private static void addNumToChar(int a, char c0) {
char c = 'a';
if(Character.isUpperCase(c0)) {
c = 'A';
}
while (a < 0) a += 26;
char c1 = (char) (c + (c0 - c + a) % 26);
System.out.println(c1);
}
Run the test as follows:
addNumToChar(2, 'B'); // D
addNumToChar(2, 'b'); // d
addNumToChar(261, 'B'); // C
addNumToChar(261, 'b'); // c
addNumToChar(-2, 'B'); // Z
addNumToChar(-2, 'b'); // z
addNumToChar(-261, 'B'); // A
addNumToChar(-261, 'b'); // a

After you add or subtract, correct with:
character = (character + 26 - 'a')%26 + 'a';
Java's x%y operator gives the remainder from integer division of x by y. Subtracting 'a' gives the offset from the start of the lowercase alphabet, and then adding 26 guarantees a positive sum, provided you didn't add an offset less than -26 or subtract more than +26.

public char number(int num, char c){ // -- num =29, char= 'd'
int n = c - 96 ; // n = 4
n = n+(num%26); // n = 4 + 3 = 7
if(n > 26){ return (char)(n-26); } // doesnot follow
else if(n < 0){ return (char)(n+26); } // doesnot follow
else { return (char)(n); } // return g
}
You can try this method. It can handle positive as well as negative number.

use that one :-
public static void main(String[] args) {
char c= 'a' - 1;
if(!(c>=97 && c<=122)) {
if(c>=123)
c= (char) (c-26);
else
c= (char) (c+26);
}
System.out.println(c);
}

Related

Trying to increment counter using character comparison

I'm writing a method that is supposed to iterate through a string and increment a counter each time the letter c is found. The method uses the count to calculate the proportion of the string that was c. I added print statements to investigate why it was wrongly returning 0.0 for a string that had some c's in it.
I have tried declaring the counter as an int and then casting it to double later but that didn't help.
public double cRatio() {
String dna = "ATCCCCCCGTACCTAGCAA";
double cCount = 0.0;
for (int i = 0; i < dna.length(); i++) {
char ch = dna.charAt(i);
if (ch == 'c') {cCount++;}
}
System.out.println("C Count is : " + cCount);
System.out.println("dna.length() is : " + dna.length());
double cgRatio = (cCount / dna.length());
System.out.println("C Ratio is : " + cgRatio);
return cgRatio;
}
I expect the counter to have value 9.0 at the time it prints but instead, it is 0.0.
Your code does not count the letter c because you are checking for the letter C. The small c does not equal the upper C (different ASCII code).
if (ch == 'C') {cCount++;}
This will fix your problem.

How do I get the numerical value/position of a character in the alphabet (1-26) in constant time (O(1)) without using any built in method or function?

How do I get the numerical value/position of a character in the alphabet (1-26) in constant time (O(1)) without using any built in method or function and without caring about the case of the character?
If your compiler supports binary literals you can use
int value = 0b00011111 & character;
If it does not, you can use 31 instead of 0b00011111 since they are equivalent.
int value = 31 & character;
or if you want to use hex
int value = 0x1F & character;
or in octal
int value = 037 & character;
You can use any way to represent the value 31.
This works because in ASCII, undercase values are prefixed with 011, and uppercase 010 and then the binary equivalent of 1-26.
By using the bitmask of 00011111 and the AND operand, we covert the 3 most significant bits to zeros. This leaves us with 00001 to 11010, 1 to 26.
Adding to the very good (self) answer of Charles Staal.
Assuming ascii encoding following will work. Updated from the kind comment of Yves Daoust
int Get1BasedIndex(char ch) {
return ( ch | ('a' ^ 'A') ) - 'a' + 1;
}
This will make the character uppercase and change the index.
However a more readable solution (O(1)) is:
int Get1BasedIndex(char ch) {
return ('a' <= ch && ch <= 'z') ? ch - 'a' + 1 : ch - 'A' + 1;
}
One more solution that is constant time but requires some extra memory is:
static int cha[256];
static void init() {
int code = -1;
fill_n (&cha[0], &cha[256], code);
code = 1;
for(char s = 'a', l = 'A'; s <= 'z'; ++s, ++l) {
cha[s] = cha[l] = code++;
}
}
int Get1BasedIndex(char ch) {
return cha[ch];
}
We can get their ASCII values and then subtract from the starting character ASCII(a - 97, A - 65)
char ch = 'a';
if(ch >=65 && ch <= 90)//if capital letter
System.out.println((int)ch - 65);
else if(ch >=97 && ch <= 122)//if small letters
System.out.println((int)ch - 97);
Strictly speaking it is not possible to do it portably in C/C++ because there is no guarantee on the ordering of the characters.
This said, with a contiguous sequence, Char - 'a' and Char - 'A' obviously give you the position of a lowercase or uppercase letter, and you could write
Ord= 'a' <= Char && Char <= 'z' ? Char - 'a' :
('A' <= Char && Char <= 'Z' ? Char - 'A' : -1);
If you want to favor efficiency over safety, exploit the binary representation of ASCII codes and use the branchless
#define ToUpper(Char) (Char | 0x20)
Ord= ToUpper(Char) - 'a';
(the output for non-letter character is considered unspecified).
Contrary to the specs, these snippets return the position in range [0, 25], more natural with zero-based indexing languages.

Decoding sentences in Java using arrays

So I am doing some practice problems for an upcoming exam and one of the problems is posing a bit of a challenge to me.
The problem states that our code should take a string that has been encoded and decode it. It must work as follows:
Each letter is decoded using the letter immediately before it in the alphabet ("b" becomes "a", "c" becomes "b" ect.)
"a" becomes "z".
each digit works the same way, 8 becomes 7, 5 becomes 4.
0 becomes 9.
characters neither letters nor digits are unchanged.
THE ONLY JAVA METHOD I CAN USE IS IO
Ex:
NFFU NF BU 23 JO UIF CFMM UPXFS
meet me at 12 in the bell tower
heres my current code, i cannot decide whether to use for loops or not. TBH I am not really sure how to tackle this.
public class prb1 {
public static void main(String[] args) {
char letter[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
int num[]={0,1,2,3,4,5,6,7,8,9};
System.out.println("Enter Message");
String mssg=IO.readString();
for(char i=0; i<letter.length; i++){
System.out.print(letter[i]--);}
for(int j=0; j<num.length; j++){
System.out.print(num[j]--);
}
}
}
The basic is like this. But this doesn't account yet for the a => z conversion.
String cypher ="ABCDEF";
String plain = "";
for (char c : cypher.toCharArray())
plain += (char) (c - 1);
System.out.println(plain);
With the modulo A => Z, it looks like this:
int A = 'A';
plain += (char) (((c - A - 1 + 26) % 26) + A);
The +26 is needed because java says -1 % 26 == -1 instead of 25.
So this just works for A-Z, but you can easily modify it to work for wider ranges.
You can use a loop to iterate through each character of the message and subtract one from its ascii code if its not a space, an a, or an A:
String message = "NFFU NF BU 23 JO UIF CFMM UPXFS";
String result = "";
for (char thisChar : message.toCharArray()) {
if (thisChar == ' ') {
result += " ";
} else if(thisChar == 'a') {
result += 'z';
} else if (thisChar == 'A') {
result += 'Z';
} else
result += (char)(thisChar - 1);
}
}
System.out.println(result);
Alternatively, you could do:
String message = "NFFU NF BU 23 JO UIF CFMM UPXFS";
String result = "";
for (int i = 0; i < message.length(); i ++) {
char thisChar = message.charAt(i);
if (thisChar == ' ') {
result += " ";
} else if(thisChar == 'a') {
result += 'z';
} else if (thisChar == 'A') {
result += 'Z';
} else
result += (char)(thisChar - 1);
}
}
System.out.println(result);
Technically,
else if(thisChar == 'a') {
result += 'z';
} else if (thisChar == 'A') {
result += 'Z';
}
could be shortened to:
else if(thisChar == 'a' || thisChar == 'A') {
result += (char)(thisChar + 25);
}

Finding location of char in the alphabet

If I have a char, for example:
char letter = 'g'
is there a way for me to find out where in the alphabet this letter is? (assuming it is in the alphabet)
So for clarification, the answer for letter would be 7, since g is the 7'th letter in the alphabet.
For starters, you can always get the ASCII int value for a character in Java by simply casting that character to an int as follows:
char letter = 'g';
int ascii = (int) letter; # ascii = 103
To get the 1-based position in the alphabet, you can offset this value keeping in mind that character a has a value of 97:
int getPosition(char input) {
char smalla = 'a';
int alphabetStart = (int) smalla; # alphabetStart = 97
int position = (int) input - alphabetStart + 1;
return position;
}
Keep in mind that I have only considered lowercase letters of the alphabet in my solution. Uppercase characters have ASCII values which run from 65 (A) to 90 (Z), and the solution to take those into account would be a bit more complex.
Use indexOf() to get position of character from abcdefg... string
Here is the simple solution.
public static int getCharPosition(char c)
{
String line = "abcdefghijklmnopqrstuvwxyz";
int position = line.indexOf(String.valueOf(c).toLowerCase())+1;
return position;
}
Input : z
Output : 26
As being said in the comments, the easiest way to find index of a char is:
c.toLowerCase() - 'a' + 1
In the ASCII table each letter has an ordinal number. You can get the ordinal number of a char by casting it to int.
The lower case letter a has an ordinal number of 97, so you have to substract it from your letter's ordinal number. Since the ASCII table starts at ordinal number 0, substract an additional 1.
Java code:
char letter = 'g';
int asciiNumber = (int)letter; // 103
final int offset = 97 - 1; // 97 is ASCII code for 'a', -1 since ASCII table starts at 0
int numberInAlphabet = asciiNumber - offset;
System.out.println("Position of letter '" + letter + "': " + numberInAlphabet);
To handle both lowercase and uppercase you can do something like this :
public int alphabetPosition(char c) {
int a='a';
int position=(String.valueOf(c).toLowerCase().codePointAt(0))-a+1;
return position;
}
public class SearchAlphabet {
public static void main(String args[])
{
char letter='d';
int ascii=97; //ascii value of a
int counter=1;
for(int a=0;a<=27;a++)
{
if(ascii==(int)letter)
{
System.out.println("Position");
System.out.println(counter);
break;
}
ascii++;
counter++;
}
}
}
Here,we start counter from 1 and incremented by 1 on every iteration after matching the given character ascii.And after matching the with concern character, we print the counter value.

How to rotate a single character based on a specific range of ascii characters in Java?

I am trying to come up with a function that accepts a character and a number. The number is the number of times the character should be "rotated". The accepted ASCII codes are 32 to 126.
Example of rotate = If a character "A" was rotated twice, it would end up as the character "C". If "A" was rotated three times, it would end up as the letter "D". If you look at the ASCII table:
http://www.jimprice.com/ascii-0-127.gif
Given my limit of the ASCII value being 32 to 126... ascii value 065 rotated would be ascii value 067. ascii value 124 rotated 5 times would be ascii value 34.
For example:
if I passed the function "!" (ASCII code 33) and the number 2, the
output character should be "#" (ASCII code 35).
if I passed "}"
(ASCII code 125) and the number 3, I should get the output character
"!" (ASCII code 33).
What is the best way to accomplish this in java (can it support negative numbers for the distance to rotate instead of just positive if you want to rotate the other way around)?
Try something like:
static char rotate(char c, int distance) {
assert 32 <= c && c < 127;
if (distance < 0) distance = distance % (127 - 32) + 127 - 32;
return (char) ((c + distance - 32) % (127 - 32) + 32);
}
Edit: Added the if (distance... line to support negative distances.
Do like this
public static char numToChar(int num,int rotate){
int result = num+rotate;
if(result>126){
result =31+(result-126);
}
return (char)result;
}
System.out.println(numToChar(33,2));
System.out.println(numToChar(125,3));
Output
#
!
You could use this approach
public static char rotateChar(char in, int shift) {
/* cast char to int */
int v = (int) in;
/* to cover wrap-around */
v += (shift % 95);
/* 32 - 126 = -95 */
return (char) ((v > 126) ? v - 95 : v);
}
public static void main(String[] args) {
System.out.printf("! + 2 = %s\n",
String.valueOf(rotateChar('!', 2)));
System.out.printf("} + 3 = %s\n",
String.valueOf(rotateChar('}', 3)));
System.out.printf("b - 1 = %s\n",
String.valueOf(rotateChar('b', -1)));
}
! + 2 = #
} + 3 = !
b - 1 = a
Try This.
public static void main(String[] args) {
String ascii;
String rotate;
Scanner in = new Scanner(System.in);
System.out.println("Enter ASCII Character");
ascii = in.nextLine();
System.out.println("Enter Rotate value");
rotate = in.nextLine();
int output=(Integer.parseInt(ascii)+Integer.parseInt(rotate))% 126;
if(output<32) output=output+32;
System.out.println("output="+output);
System.out.println(Character.toString ((char) output));
}

Categories

Resources