Need to find difference between two characters(Alphabet is cyclic) - java

Given a string, "azza". In this a-z = 25, z-z = 0, z-a = 25. But since alphabet is cyclic, I need 'a' just after 'z' i.e., in the above string z-a = 1.
For normal string where we dont encounter 'a' just after 'z', my code is this
class TestClass {
public static void main(String args[] ) throws Exception {
Scanner sc = new Scanner(System.in);
int i;
int t = sc.nextInt();
sc.nextLine();
for(i=0;i<t;i++)
{
String s =sc.nextLine();
char[] string =s.toCharArray();
for(i=0;i<string.length;i++)
{
if((string[i]-string[i+1])==1 || (string[i]-string[i+1])==-1)
{
System.out.println("1");
}
}
}
}
}

First, reverse subtractions: when you need to compute z-a in your scheme, compute 'a'-'z' and vice versa.
This way you can sometimes arrive at a negative result. When this happens, add 26 to it. This would act as "circling back" to the beginning.
char first = 'a';
char last = 'z';
int diff = first - last; // negative 25
if (diff < 0) {
diff += 26;
}
Demo.

Related

Is there any way to sort the digits of an Integer without any ARRAY in JAVA?

I am trying to sort the digits of an Integer in descending order in JAVA but I am not allowed to use any array.
This was given to me as an assignment in class and below is a code that I tried but failed.
import java.util.Scanner;
class descend
{
public static void main(String args[])
{
int a=0,loc=0,parse=0,temp=0,big=0;
Scanner scan = new Scanner(System.in);
System.out.print("Enter a number");
a=scan.nextInt();
String s=Integer.toString(a);
int l=s.length();
for(int i=0;i<l;i++)
{
big=(int)(s.charAt(i));
loc=i;
for(int j=i+1;j<l;j++)
{
parse=(int)(s.charAt(j));
if(parse>big)
{
big = parse;
loc=j;
}
}
temp=parse;
s.charAt(i)=s.charAt(loc);
s.charAt(loc)=temp
}
System.out.print(s);
}
}
Here I get a syntax error at s.charAt(i)=s.charAt(loc); and s.charAt(loc)=temp; that a variable is required but a value is given.
Please help me out with this and I shall always be grateful to you.
Maybe the teacher want to test your knowledge about the new stream API. Or maybe he wants you to test your knowledge about Collections.sort() and LinkedList (which does not contain an internal array).
1.) Here is a solution with stream API:
int number = 52214;
String.valueOf(number).chars()
.sorted()
.map(Character::getNumericValue).forEach(System.out::print);
This will print out:
12245
2.) Here is a solution with collections:
List<Integer> list = new LinkedList<Integer>();
StringCharacterIterator iterator = new StringCharacterIterator(String.valueOf(number));
for (char c = iterator.first(); c != CharacterIterator.DONE; c = iterator.next())
{
list.add(Character.getNumericValue(c));
}
Collections.sort(list);
System.out.println("list=" + list);
This will print out:
list=[1, 2, 2, 4, 5]
String cannot be changed, only replaced, hence a = b; f(b); will never change a.
With 10 digits only, you could iterate, step through, from 0 upto 9 to have the sorting:
int number = ... // or String number
if (number == 0) { // or < 10
System.out.println(number);
} else {
for (int digit = 0; digit <= 9; ++digit) {
// While being able to remove the current digit:
for (;;) {
int scrapedNumber = numberWithoutDigitOnce(number, digit);
if (scrapedNumber == number) {
break;
}
number = scrapedNumber;
System.out.print(digit);
}
}
System.out.println();
}
int numberWithoutDigitOnce(int number, int digit) {
if (number % 10 == digit) {
return number / 10;
}
int n = numberWithoutDigitOnce(number/10, digit)*10 + (number % 10);
}
Zero is a special case.
A recursive solution, you find the highest digit in the String, add it to your output String, and remove it from your input String.
Repeat until your input String is empty.
Removing the character at a given index in a String can be achieve by concatenating the characters before the index and the ones after the index. (Or with a StringBuilder but I agree with the comments on the OP that it would be cheating to use a StringBuilder)
private static String sort(String digitsLeftToSort, String sortedString) {
if(digitsLeftToSort.length() == 0) { // no more character to sort
return sortedString;
} else {
// find the index of the highest digit
int index = findIndexOfHighestDigit(digitsLeftToSort);
// add the character at that index to your output String
sortedString += digitsLeftToSort.charAt(index);
// Remove it from your input String
digitsLeftToSort = digitsLeftToSort.substring(0, index) + digitsLeftToSort.substring(index+1);
// Recursive call with your new Strings
return sort(digitsLeftToSort, sortedString);
}
}
// This finds the index of the highest digit in the given String
private static int findIndexOfHighestDigit(String s) {
int highestDigitValue = -1;
int highestDigitIndex = -1;
int integerValue;
for(int i = 0; i< s.length(); i++) {
integerValue = Character.getNumericValue(s.charAt(i));
if(integerValue > highestDigitValue) {
highestDigitValue = integerValue;
highestDigitIndex = i;
}
}
return highestDigitIndex;
}
Then
String sortedString = sort("462375623478142", "");
System.out.println(sortedString);
Outputs
877665444332221
Sorry, But after applying so much effort, I figured it out.
int n=54321;char ch;
String s=Integer.toString(n);
int l= s.length();
for(int i=48;i<=57;i++) //ascii values from 0 - 9
{
for(int j=0;j<l;j++)
{
ch=s.charAt(j);
if(ch==(char)i) // checking if a digit equals a number
{
System.out.print(ch);
}
}
}
It sorts the digits in ascending order. To sort in descending order we should use
for(int i=57;i>=48;i--)

Creating a Character Array with a Certain Number of Vowels and Consonants (Java)

I am trying to create a program that outputs ten lowercase letter characters - five vowels and five consonants. In order to do this, I have started by creating a char array with a range between 'a' and 'z' called letters[] with size 10. Once the array is filled, I will print the output with the use of a format string containing everything in the array.
My question is, how would I make the program output exactly five of each type (and keep the order of the characters printed completely random)? I have considered using the switch statement with a case each for consonants and vowels, but my ideas so far seem over-complicated and inelegant.
Code so far:
char letters[] = new char[10];
for(int i = 0; i < letters.length; i++){ //Open for
letters[i] = (char)(97 + Math.random() * 26);
char idx = letters[i];
System.out.printf("%s",idx);
} //End for
If you don't mind a somewhat more String-related solution, here is one. I am assuming that you don't want any consonant or vowel repeated in the output string, so this algorithm removes letters for consideration once they've been used. It also provides a bit more of a generic letter picker routine that's not really limited to vowels and consonants.
import java.lang.StringBuilder;
public class Shuffler {
public static String CONSONANTS = "bcdfghjklmnpqrstvwxyz";
public static String VOWELS = "aeiou";
/*
* Returns a new string that is a combination of the current string and 'count'
* characters from the source string (using any character in the source string
* no more than one time).
*/
public static String shuffleIntoString(String current, String source, int count) {
if (current == null || source == null || count < 0 || count > source.length()) {
System.out.println("Error in parameters to shuffleIntoString");
return null;
}
StringBuilder retval = new StringBuilder(current); // build up by inserting at random locations
StringBuilder depletedSource = new StringBuilder(source); // remove characters as they are used
for (int i = 0; i < count; i++) {
int pick = (int) (Math.random() * depletedSource.length());
int whereToInsert = (int) (Math.random() * retval.length());
retval = retval.insert(whereToInsert, depletedSource.charAt(pick));
depletedSource.deleteCharAt(pick);
}
return retval.toString();
}
public static void main(String[] args) {
Shuffler shuf = new Shuffler();
for (int i = 0; i < 10; i++) {
String result = shuf.shuffleIntoString("", shuf.CONSONANTS, 5);
result = shuf.shuffleIntoString(result, shuf.VOWELS, 5);
System.out.println(result);
}
}
}
And the output looks like this:
kqoibauzed
uhcawoerib
afdzoemius
yuagocibej
eiuhaokcyq
ouveiawrxn
uyaiveomxn
ruxeoalhij
uraliwfeoc
afoutiesmr
This will achieve what you desire if you are content with using ArrayLists. To generate the random chars you could generate a number within the index of the corresponding char Strings and add the value to the ArrayList. Collections is a helpful Class that you can use to shuffle the list.
List<Character> list = new ArrayList<>();
String consonants = "bcdfghjklmnpqrstvwxyz";
String vowels = "aeiou";
Random r = new Random();
for (int i = 0; i < 5; i++) {
list.add(consonants.charAt(r.nextInt(consonants.length()))); // Add consonant
list.add(vowels.charAt(r.nextInt(vowels.length()))); // Add vowel
}
Collections.shuffle(list);
for (Character c : list) {
System.out.println(c);
}
I don't seen any rules about duplicated but if you want you can remove latters from arrays after selection.
List<Character> vowels = Arrays.asList('a', 'e', 'i', 'o', 'u');
List<Character> consonants = new ArrayList<>();
for (char latter = 'a'; latter <= 'z'; latter++) {
if(!vowels.contains(latter)) {
consonants.add(latter);
}
}
final Random random = new Random();
int vowelsRemain = 5;
int consonantsRemain = 5;
List<Character> result = new ArrayList<>();
while (vowelsRemain > 0 && consonantsRemain > 0) {
final boolean generateVowel = random.nextBoolean();
final char randomLatter;
if(generateVowel) {
randomLatter = vowels.get(random.nextInt(vowels.size()));
vowelsRemain--;
} else {
randomLatter = consonants.get(random.nextInt(consonants.size()));
consonantsRemain--;
}
result.add(randomLatter);
}
while (vowelsRemain > 0) {
final Character randomVowel = vowels.get(random.nextInt(vowels.size()));
result.add(randomVowel);
vowelsRemain--;
}
while (consonantsRemain > 0) {
final Character randomConsonant = consonants.get(random.nextInt(consonants.size()));
result.add(randomConsonant);
consonantsRemain--;
}
System.out.println(result);

How to randomize the case of letters in a string

I want to write some automated tests for web app authentication. The login password is case-sensitive and always contains at least one alphabetic character.
I want to write a test where I randomly change the case of one or more alphabetic characters.
Let's say the password string is "123te123st!".
Now I want to change this string to one which contains at least one uppercase letter. I'm trying to make sure that the login is still case-insensitive and any variation in case will fail to match the password.
Does anybody know a elegant way to do it? I searched already (including Apache Commons) but couldn't find a helper method.
You can look at the randomAlphaNumeric from the RandomStringUtils, although it would seem that you are not guaranteed for it to have an upper case. To go around this, you could get the first lowercase letter and use the .toUpper() method to get it to upper case.
Alternatively, you could generate random numbers between 0 and 9 and 65 and 90 and 97 and 122. The first set should get you random numbers, you could then cast the second number to a character to get your upper case letter(s) and do the same on the last number to get your lower case ones.
That being said, when testing one usually goes for data which is predetermined rather than generating data on the fly, since that would make it easier to debug. Having a simple pool of passwords might also be easier to implement and would also allow you to better test edge cases.
class Case
{
public static void main(String ar[])
{
String s = "upperCase",split[];
split = s.split("");
int len = s.length(),i=0;
while(i!=len)
{
if(split[i].toUpperCase() == split[i])
{
System.out.println("Password Contains One UpperCase Latter");
break;
}
i++;
}
}
}
By using this code u can easily check whether string contain uppercase or not.
if output prints "Password Contains One Uppercase Latter" this message then string contain at least on uppercase.
In this case output would like:
You can use this class to generate random passwords with a constraint on uppercase letters.
import java.util.Random;
public class RandomPasswordGenerator {
private static final String ALPHA_CAPS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String ALPHA = "abcdefghijklmnopqrstuvwxyz";
private static final String NUM = "0123456789";
private static final String SPL_CHARS = "!##$%^&*_=+-/";
public static char[] generatePswd(int minLen, int maxLen, int noOfCAPSAlpha,
int noOfDigits, int noOfSplChars) {
if(minLen > maxLen)
throw new IllegalArgumentException("Min. Length > Max. Length!");
if( (noOfCAPSAlpha + noOfDigits + noOfSplChars) > minLen )
throw new IllegalArgumentException
("Min. Length should be atleast sum of (CAPS, DIGITS, SPL CHARS) Length!");
Random rnd = new Random();
int len = rnd.nextInt(maxLen - minLen + 1) + minLen;
char[] pswd = new char[len];
int index = 0;
for (int i = 0; i < noOfCAPSAlpha; i++) {
index = getNextIndex(rnd, len, pswd);
pswd[index] = ALPHA_CAPS.charAt(rnd.nextInt(ALPHA_CAPS.length()));
}
for (int i = 0; i < noOfDigits; i++) {
index = getNextIndex(rnd, len, pswd);
pswd[index] = NUM.charAt(rnd.nextInt(NUM.length()));
}
for (int i = 0; i < noOfSplChars; i++) {
index = getNextIndex(rnd, len, pswd);
pswd[index] = SPL_CHARS.charAt(rnd.nextInt(SPL_CHARS.length()));
}
for(int i = 0; i < len; i++) {
if(pswd[i] == 0) {
pswd[i] = ALPHA.charAt(rnd.nextInt(ALPHA.length()));
}
}
return pswd;
}
private static int getNextIndex(Random rnd, int len, char[] pswd) {
int index = rnd.nextInt(len);
while(pswd[index = rnd.nextInt(len)] != 0);
return index;
}
}
You can try like this:
public class Test{
public static void main(String[] args){
String s = "1a23test12hjsd2"; // Take it as a password
char[] c= s.toCharArray(); //Convert string in chararray
boolean flag= false;
StringBuilder s1= new StringBuilder();
for(int d:c){
if(d>=97 && d<=122 && !flag){ //Converting lowercase to upper case
d=d-32;
flag=true;
}
s1.append((char)d);
}
System.out.println(s1);
}
}
To generate all capitalized variants of a string, it makes sense to scan the string and store the position of each letter in a list. This will let you iterate over the letters while skipping the non-letter characters.
For example, for the string "_a_b_c_", you want to store the positions [1, 3, 5].
Next, make a boolean array of the same length as the list of letter positions. This will represent the positions of letters that have had their case inverted.
To generate the next capitalized variant, pretend that the boolean array represents a binary number in reverse. Add 1 to that boolean number, which means scanning the array from the beginning, flipping each true to false until you reach a false, which you flip to true. As you flip each bit, invert the case of the corresponding character in the string.
Thus, we get the following 23 - 1 = 7 variants of "_a_b_c_":
binary number reversed capitalized variant
001 100 _A_b_c_
010 010 _a_B_c_
011 110 _A_B_c_
100 001 _a_b_C_
101 101 _A_b_C_
110 011 _a_B_C_
111 111 _A_B_C_
Here is a complete Java implementation.
import java.util.*;
import java.io.*;
public class VaryCaps {
int wordLength,
numLetters;
Integer letterPositions[];
boolean inverted[];
StringBuffer buffer;
public VaryCaps(String word) {
wordLength = word.length();
List<Integer> positionList = new ArrayList<Integer>();
for (int i = 0; i < wordLength; ++i) {
if (Character.isLetter(word.charAt(i))) {
positionList.add(i);
}
}
numLetters = positionList.size();
letterPositions = positionList.toArray(new Integer[numLetters]);
inverted = new boolean[numLetters];
buffer = new StringBuffer(word);
}
private void invert(int index) {
int pos = letterPositions[index];
char ch = buffer.charAt(pos);
if (Character.isUpperCase(ch)) {
ch = Character.toLowerCase(ch);
} else {
ch = Character.toUpperCase(ch);
}
buffer.setCharAt(pos, ch);
inverted[index] = !inverted[index];
}
public String next() {
int index = 0;
while (index < numLetters && inverted[index]) {
invert(index++);
}
if (index == numLetters) {
return null;
}
invert(index);
return buffer.toString();
}
public static void main(String[] args) {
VaryCaps rc = new VaryCaps("_a_b_c_");
String s;
while ((s = rc.next()) != null) {
System.out.println(s);
}
}
}

How do I store these printed letters into an array?

Right now this program prints out the alphabet (a-z) however I want to take those letters and store each one in the array called leta, how do i do that?
public class Arrayofhope {
public static void main (String[]args) {
char []leta = new char[26];
char letter = (char)65;
char lettter=(char)90;
for (int i = letter;i<=lettter;i++ ) {
System.out.print((char)i);
}
}
}
This is almost a "syntax" type question, but it's also tricky enough that there's some value to pointing out how it works.
class Arrayofhope
{
public static void main( String[] args )
{
char[] leta = new char[ 26 ];
char letterA = 'a';
char letterZ = 'z';
for( int i = letterA; i <= letterZ; i++ ) {
System.out.print( (char) i );
leta[i-'a'] = (char)i;
}
}
}
Characters in single quotes are the same as integers of type char. You can assign them and do math on them. I think this makes the initial assignment of char letterA = 'a'; more clear than using the number 65.
And as mentioned you can do math with character types too. Note the aray index [i-'a'] is calculated so that 65 is subtracted from 65 for the first character, so that 'a' is stored in index 0, and proceeding up from there. This is kinda tricky but in the long run more clear, I think, and also easier than trying to program with an ASCII table in front of you.
public class Arrayofhope {
public static void main (String[]args) {
char []leta = new char[26];
char letter = (char)65;
char lettter=(char)90;
for (int i = letter,j=0;i<=lettter;i++,j++ ) {
let[j] = (char)i;
// If you don't want new variable you can do like below
let[i-65] = (char) i;
System.out.print((char)i);
}
}
}

Reduce the value of a letter, e.g. can change 'd' to 'c', but cannot change 'c' to 'd'. In order to form a palindrome

public class Solution {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int tc = Integer.parseInt(br.readLine());//I get Numberformat Exception here
for(int i=0;i<tc;i++) // Even if my inputs are on separate lines
{
String original = br.readLine();
palindrome(original);
}
}
public static void palindrome(String original)
{
String reverse="";
int length = original.length();
for ( int i = length - 1 ; i >= 0 ; i-- )
reverse = reverse + original.charAt(i);
if (original.equals(reverse))
{
System.out.println(0);
}
else
{
char[] org = original.toCharArray();
int len = org.length;
int mid = len / 2;
if(len % 2 == 0)
{
char[] front = new char[mid];
char[] back = new char[mid];
for(int i=0;i<mid;i++)
{
front[i] = org[i];
}
int j=0;
for(int i=len-1;i>=mid;i--)
{
back[j] = org[i];
j++;
while(j > mid)
{
break;
}
}
change(front,back,mid);
}
else
{
char[] front = new char[mid];
char[] back = new char[mid];
for(int i=0;i<mid;i++)
{
front[i] = org[i];
}
int j=0;
for(int i=len-1;i>mid;i--)
{
back[j] = org[i];
j++;
while(j > mid)
{
break;
}
}
change(front,back,mid);
}
}
}
public static void change(char[] front,char[] back,int len)
{
int count =0;
for(int i =0;i<len;i++)
{
if(front[i] != back[i] )
{
count += (back[i] - front[i]);
}
}
System.out.println(count)
}
}
What i try to do here is get an input from the number of test cases say 3 in my first line followed by the test-cases themselves.
sample input :
3
abc
abcba
abcd
Now it has to check if the string is a palindrome if its so it ll print 0
else it breaks the string into two halves front and back and finds the minimum number of changes to make it a palidrome.
here i have also checked if its a odd or even length string if odd i have omitted the middle char.
By changes we can only change 'd' to 'b' not 'b' to 'd'
Once a letter has been changed to 'a', it can no longer be changed.
My code works fine for the above input but it doesnt for some other inputs i dont quiet understand why..
for instance if i give a custom test case as
5
assfsdgrgregedhthtjh
efasfhnethiaoesdfgv
ehadfghsdfhmkfpg
wsertete
agdsjgtukgtulhgfd
I get a Number Format Exception.
Your code works fine here, whithout NumberFormatException: http://ideone.com/QJqjmG
This may not solve your problem, but improves your code...
As first user input you are expecting an integer. You are parsing the String returned by br.readLine() and do not take care of the NumberFormatException parseInt(...) may throw.
Just imagine someone hits space or return key as first input.
So I propose to put a try-catch-block around the parseInt(...). Here is an example how this may look like.
Guys thank you for all your suggestion i just found out why my other test cases weren't working
public static void change(char[] front,char[] back,int len)
{
int count =0;
for(int i =0;i<len;i++)
{
if(front[i] != back[i] )
{
count += (back[i] - front[i]);
}
}
System.out.println(count)
}
This part of my code has to be changed to
public static void change(char[] front,char[] back,int len)
{
int count =0;
for(int i =0;i<len;i++)
{
if(front[i] != back[i] )
{
char great = findGreatest(front[i],back[i]);
if(great == back[i])
{
count += (back[i] - front[i]);
}
else
{
count += (front[i] - back[i]);
}
}
}
System.out.println(count);
}
public static char findGreatest(char first,char second)
{
int great = first;
if(first < second)
{
great = second;
}
return (char)great;
}
Because i get negative values coz of subtracting ascii's which are greater than them and as i have already mentioned i can only do 'd' to 'a' not the other way round.
Thank you for your time guys!

Categories

Resources