Ok,I'm just an amateur in programming,so go easy on me. So, I'm coding the classic toggle cases program but without using the .toUpperCase() or the .toLowerCase() functions but instead using ASCII values of the characters. I manage to convert the upper cases to lower but cant seem to do the opposite.
package toggle;
import java.util.Scanner;
public class Toggle {
String str;
Scanner sc=new Scanner(System.in);
public void toggleStr()
{
System.out.println("Enter a string");
str=sc.nextLine();
char c;
int res;
char ch[]=str.toCharArray();
for(int i=0;i<ch.length;i++)
{
res=(int)(ch[i]);
if((res>=65)||(res<=90))
{
c=(char)(res+32);
System.out.print(c);
}
else if((res>=97)||(res<=122))
{
c=(char)(res-32);
System.out.print(c);
}
else
System.out.print(ch[i]);
}
}
public static void main(String[] args)
{
Toggle t=new Toggle();
t.toggleStr();
}
}
|| should be &&, in both cases. Any number is greater than 65 or less than 90, so the first if block gets executed each time, regardless of the character.
All values from 97 to 122 are greater than 65, so your first if condition will include the lower case as well as the upper case characters. You need to use && instead of || (and instead of or).
If we are talking about good old ASCII table then each small letter differ from big letter by only one bit (2^5, 6th bit) represented by decimal 32 or hex 0x20.
But if we are talking about XXI century unicode we can use the java std library functions.
Below I show both versions:
ASCII style:
public String toggleAscii(String s) {
StringBuilder sb = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') {
boolean isLower = (c & 0x20) == 0x20; // binary 100000 (sixth bit, 2^5)
c = (char) (isLower ? (c & 0xdf) : (c | 0x20));
}
sb.append(c);
}
return sb.toString();
}
Unicode style:
public String toggle(String s) {
StringBuilder sb = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
boolean isUpper = Character.isUpperCase(c);
sb.append(isUpper ? Character.toLowerCase(c) : Character.toUpperCase(c));
}
return sb.toString();
}
Related
I'm a beginner at java and can't get this code to work. What I have to do is convert any inputted string to uppercase without using the toUpperCase string method. This is what I have:
public String toUpperCase(String str)
{
for(int i = 0; i < str.length(); i++)
{
char a = str.charAt(i);
a = Character.toUpperCase(a);
str += Character.toString(a);
}
return str;
}
You are using str as input, and output (so your String has infinite length, as you keep adding characters). And you can use static, because you aren't using instance state. And, you might use a for-each loop. Finally, add another String, or better a StringBuilder like
public static String toUpperCase(String str) {
StringBuilder sb = new StringBuilder();
for (char ch : str.toCharArray()) {
sb.append(Character.toUpperCase(ch));
}
return sb.toString();
}
There is the following way, but it doesn't consider any characters outside of English (no diacritics, no other languageās characters behind a-z).
public String toUpperCase(String str) {
char[] chars = str.toCharArray();
for (int i=0; i<chars.length; i++) {
char c = chars[i];
if ('a' <= c && c <= 'z') {
chars[i] = (char) (c - 'a' + 'A');
}
}
return new String(chars);
}
I am aware your school probably do not allow you to use StringBuilder and in case you can't use array as well. This is another primitive approach which your school may accept:
public static String toUpperCase(String s){
String str = "";
for(int x=0; x<s.length(); x++){
char ch = s.charAt(x);
if(ch >= 'a' && ch <= 'z')
str += "" + (char)(ch - 32);
else
str += "" + ch;
}
return str;
}
Test:
System.out.println(toUpperCase("aAbBcC"));
Output:
AABBCC
Since you can't use the toUpperCase() method, you can use the ASCII table to get from a lower case letter to an upper case letter by subtracting 32.
'a' = 97, 'A' = 65
'b' = 98, 'B' = 66
...
'z' = 122, 'Z' = 90
public static int DIFF = 'a' - 'A'; // 32
public static String toUpperCase(String str) {
StringBuilder sb = new StringBuilder();
for (char c : str.toCharArray()) {
if (Character.isLowerCase(c)) {
sb.append(String.valueOf((char)(c - DIFF)));
} else {
sb.append(c);
}
}
return sb.toString();
}
try it:
public static String toUpperCase(String str) {
String result = "";
for (int i = 0; i < str.length(); i++) {
int v = str.charAt(i);
if (v > 96 && v < 123) {
v -= 32;
}
result+=(char)v;
}
return result;
}
C'mon guys, Java 8 has been out for years!
/**
* Converts an all-lowercase String to
* uppercase. Retains only spaces, any
* other characters will be lost.
*/
public static String toUpperCase(String s) {
int diff = 'a' - 'A'; // 32
return s.chars()
.filter(c -> c >= 'a' && c <= 'z' || c == ' ')
.mapToObj(c -> String.valueOf((char) (c - (diff))))
.collect(Collectors.joining());
}
Trying to complete this challenge from coderbyte: "Using the Java language, have the function LetterChanges(str) take the str parameter being passed and modify it using the following algorithm. Replace every letter in the string with the letter following it in the alphabet (ie. c becomes d, z becomes a). Then capitalize every vowel in this new string (a, e, i, o, u) and finally return this modified string."
The problem that i am having is the replace is pulling on the white spaces between characters, but I need it to preserve white spaces between words. Is there a better solution to this?
import java.util.Arrays;
import java.util.Scanner;
public class nextLetter {
public static String LetterChanges(String str) {
String[] inputString = str.replaceAll("[^a-zA-Z ]", "").split("");
String[] alph= "abcdefghijklmnopqrstuvwxyz".split("");
String[] vowel ="aeiouy".split("");
for(int i=0; i<inputString.length; i++){
int index= Arrays.asList(alph).indexOf(inputString[i])+1;
inputString[i]= alph[index];
if(Arrays.asList(vowel).indexOf(inputString[i])>0){
inputString[i]= inputString[i].toUpperCase();
}
}
//System.out.println(Arrays.toString(inputString));
return Arrays.toString(inputString)
.replace(" ","")
.replace(",", "") //remove the commas
.replace("[", "") //remove the right bracket
.replace("]", "")//remove the left bracket
.replace(" ","")
.trim();
}
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("enter a sentence");
System.out.print(LetterChanges(s.nextLine()));
}
}
Also I would not mind any pointers on how to improve this!
Note: I've changed the method name to something a bit more descriptive. The method assumes that you're only working with lowercase letters.
public static void main(String[] args){
System.out.println(shiftLetters("abcdz")); //bcdea
}
public static String shiftLetters(String str){
StringBuilder shiftedWord = new StringBuilder();
for (int i = 0; i < str.length(); i++){
char currentChar = str.charAt(i);
if (currentChar != ' '){
currentChar += 1;
if (currentChar > 'z'){
currentChar = 'a';
}
}
shiftedWord.append(currentChar);
}
return shiftedWord.toString();
}
This is the general logic flow of this program: create a cumulative StringBuilder object that will eventually be the return value of the method. Loop through all characters in the string; if the character is a whitespace character, then simply don't bother with it and add it onto the StringBuilder as is. Else, add one to the current character. Note that chars are an integral(4.2.1) primitive type, so you may add ints to a char as such. If it's the special case that the new char is out of the normal a-z range, set it back to a.
Taking Use of Java 8's API
public static String functionalShiftLetters(String str){
return str
.chars()
.map(c -> c != ' ' ? c + 1 : c)
.map(c -> c > 'z'? 'a' : c)
.collect(StringBuilder::new,
StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
This preserves all other characters and handles the vowels.
public static String LetterChanges(String str)
{
str = str.toLowerCase();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++)
{
char c = str.charAt(i);
if ('a' <= c && c <= 'z')
{
c = (c == 'z') ? 'a' : (char) (c + 1);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
{
c = Character.toUpperCase(c);
}
}
sb.append(c);
}
return sb.toString();
}
Input: abcdefghijklmnopqrstuvwxyz 1234567890
Output: bcdEfghIjklmnOpqrstUvwxyzA 1234567890
If have fixed alphabeth and swapping algorithm you can use a static dictionary.
public static HashMap<String,String> dictionary = new HashMap<>();
static{
dictionary.put(" ", " ");
dictionary.put("a", "b");
dictionary.put("b", "c");
dictionary.put("c", "d");
dictionary.put("d", "E");
.
.
dictionary.put("z", "A");
}
public static String shiftLetters(String str){
StringBuffer response = new StringBuffer();
for (int i = 0; i < str.length(); i++){
response.append(dictionary.get(String.valueOf(str.charAt(i))));
}
return response.toString();
}
import java.util.*;
class Dis {
static boolean Digitinstring(String s) {
boolean result = false;
int i, j;
char[] ch = s.toCharArray();
int x = ch.length;
for (j = 0; j < x; j++) {
for (i = 0; i <= 9; i++) {
if (ch[j] == i) {
System.out.println("True");
result = true;
} else {
result = false;
}
}
}
return result;
}
public static void main(String args[]) {
System.out.println("Enter the string");
Scanner ob = new Scanner(System.in);
String s = ob.nextLine();
System.out.println(Digitinstring(s));
}
}
This code always gives the answer false. The if condition is not working.
What can I do to make it work properly?
Your code is failing because '3' does not equal 3. The character 3, which is your ch[j] will never be equal to an actual integer because they have different types. If you want this to work, you should replace your if condition with this:
Character.getNumericValue(ch[j]) == i;
An easier approach to this would be to simply use
Character.isDigit(s.charAt(j));
Your whole method would look like this:
public static boolean digitInString(String s){
for(int i = 0; i<s.length(); i++){
if(Character.isDigit(s.charAt(i))){
return true;
}
}
return false;
}
You can use regular expressions for more compact code. Regular expressions are good for exactly your scenario, which is looking for specific patterns in Strings. In your Digitinstring you can do the following:
return s.matches(".*\\d.*");
That returns true if your string has any number of characters (.*) followed by a digit (\\d) followed by any number of characters (.*). Any number of characters can include 0.
Swailem95's post well explains why your current implementation is not returning expected results.
/* Note: 48 to 57 is ascii values of 0,1, 2,...9 respectively
code is made more readable ascii values are not used now
*/
package com;
import java.util.Scanner;
public class Dis {
public static void main(String[] args) {
System.out.println("Enter the string");
Scanner ob = new Scanner(System.in);
String s = ob.nextLine();
System.out.println(Digitinstring(s));
ob.close();
}
private static boolean Digitinstring(String s) {
boolean result = false;
for (int j = 0; j < s.length(); j++) {
if(s.charAt(j)>='0' && s.charAt(j)<='9')
{
result=true;
break;
}
}
return result;
}
}
There are few problems. First is your else block. Remember that in case of if(){1}else{2} one of two blocks must always be executed, either it will be {1} or {2}.
It means that your result will depend only on last test, in other words on last character.
To solve this problem remove else block and let result store true only if your test will find digit.
Second problem is that, in (ch[j] == i) you are comparing char and int. So you are ending up with something like
if ('2' == 2) which is false in Java, because int representation of '2' is its index in Unicode Table, which is 50.
So as you see condition like '2'==2 is same as 50==2 which is false.
To generate all chars containing digits you can simply write for (char digit = '0'; digit<='9'; digit++) like in this code:
static boolean DigitInString(String s) {
for (char ch : s.toCharArray()) {
for (char digit = '0'; ch <= '9'; ch++) {
if (ch == digit) {
System.out.println("True");
return true;
}
}
}
return false;
}
You can also increase readability of your code and replace this nested loop
for (char digit = '0'; ch <= '9'; ch++) {
if (ch == digit) {
System.out.println("True");
return true;
}
}
with
if (Character.isDigit(ch)){
System.out.println("True");
return true;
}
This method will check if character is in range specified for digits characters in Unidoce Table.
You have a problem with:
for (i = 0; i <= 9; i++) {
if (ch[j] == i) {
System.out.println("True");
result = true;
} else {
result = false;
}
}
ch[j] is a character and i is a number, so the character '0' has a number value of 46 (if I remember correctly), so you can rectify the situation by adding '0' to i in the if statement
if (ch[j] == i+'0') {
or modifying the for loop
for (i = '0'; i <= '9'; i++) {
notice that the 0 in this case is a character.
if (ch[j] == i)
Please correct condition mentioned above to compare same object types, you currently using different types which is never true. Or use inbuilt isDigit method from Character Class.
In my program I need to insert - between two odd numbers and * between even numbers and ignore if there is 0. For example:
Input = 99946 Output = 9-9-94*6
Input = 56647304 Output = 56*6*47-304
Method getDigits() places the digits of the entered number into array cells. Method insertDashesAsteriks() returns properly concatenated String.
But when I run my program with the following example:
Please enter the numbers so they could be rearranged:
222234411110000
Exception in thread "main" java.util.InputMismatchException: For input string: "222234411110000"
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at DashInsert2.main(DashInsert2.java:9)
then I'm getting InputMismatchException. Why am I getting the error?
import java.util.Scanner;
public class DashInsert2 {
public static void main(String[] args)
{
Scanner kbd = new Scanner(System.in);
System.out.println("Please enter the numbers so they could be rearranged: ");
int nums = kbd.nextInt();
int[] numArray = getDigits(nums);
System.out.println("The array representation of the numbers is \n");
System.out.println();
String result = insertDashesAsteriks(numArray);
System.out.println("The result is " + result);
}
public static int[] getDigits(int numbers)
{
int length = Integer.toString(numbers).length();
int[] temp = new int[length];
for(int i = 0; i < length; i++)
{
temp[i] = numbers % 10;
numbers = numbers / 10;
}
return temp;
}
public static String insertDashesAsteriks(int[] numArray)
{
String temp = "";
for(int i = 1; i < numArray.length; i++)
{
if(numArray[i] % 2 == 0 && numArray[i-1] % 2 ==0)
{
temp = numArray[i-1] + "*" + numArray[i] + "*";
}
else if(numArray[i] == 0 || numArray[i-1] == 0)
{
temp = numArray[i-1] + "" + numArray[i] + "";
}
else if(numArray[i] % 2 != 0 && numArray[i-1] % 2 != 0)
{
temp = numArray[i-1] + "-" + numArray[i] + "-";
}
}
return temp;
}
}
Maximum value for int is 2,147,483,647
You entered: 222,234,411,110,000
You'll need to treat the number as a string since the number you input is past the biggest possible 32 bit integer.
Try kbd.next().charAt(0); to parse it character by character instead.
First off, if you're reading in ints, you're limited to their range. That means numbers beyond about +/- two billion are out of the question. For handling larger number, you can move to larger data types (like long) or just handle strings, which have far less stringent limitations.
Once you are handling strings, there's a far simpler way (in terms of the code you have to write) to do this substitution using regular expressions:
public class Test {
static String morph(String s) {
String oldS;
do {
oldS = s;
s = s.replaceAll("([13579])([13579])", "$1-$2");
s = s.replaceAll("([2468])([2468])", "$1*$2");
} while (! s.equals(oldS));
return s;
}
public static void main(String args[]){
System.out.println(morph("99946"));
System.out.println(morph("56647304"));
System.out.println(morph("222234411110000"));
}
}
The morph function simply modifies the string with your substitution rules until it ceases to change. The output of the test harness (using the data you supplied) is:
9-9-94*6
56*6*47-304
2*2*2*234*41-1-1-10000
Now it may be that, if this is a classwork assignment, you're limited in the language facilities you can use. But, since you haven't mentioned that, and no coder in their right mind would (usually) choose a more difficult path, you should consider the use of the regular expression method. Code that is shorter is almost always less prone to bugs.
If you don't want to use regular expressions, you can still make your code relatively short and well structured, with something like:
// Helper functions for inserting characters.
static boolean is2468 (char ch) {
return (ch == '2' || ch == '4' || ch == '6' || ch == '8');
}
static boolean is13579 (char ch) {
return (ch == '1' || ch == '3' || ch == '5' || ch == '7' || ch == '9');
}
static String morph(String str) {
// Use efficient string builder for creating morphed string.
StringBuilder newStr = new StringBuilder();
// Last/current character, starting with '0' simplifies
// start condition.
char lastCh, ch = '0';
// Process every character in string.
for (int idx = 0; idx < str.length(); idx++) {
// Transfer previous current to last, get current.
lastCh = ch;
ch = str.charAt(idx);
// Put '-' between two odds, '*' between two non-zero evens.
if (is13579(lastCh) && is13579(ch))
newStr.append('-');
else if (is2468(lastCh) && is2468(ch))
newStr.append('*');
// Put character there regardless.
newStr.append(ch);
}
// Return string version of string builder.
return newStr.toString();
}
I want to define a method that input a string then return a string which character in it has been convert
public static String encode(String s){
char[] newArray = {'a','b','c','d','e','f','g','h','i','g','k','l','m'};
char[] newArray2 = {'n','o','p','q','r','s','t','u','v','w','s','y','z'};
for(int i=0; i<s.length();i++){
if(s.charAt(i) == newArray[i]){
s.replace(newArray[i], newArray2[i]);
}
}
return s;
}
public static void main(String[] args){
System.out.println(encode("firefly"));
}
but compiler just return firefly, I know there is a problem in s.charAt(i) == newArray[i] but how to define a method , for example, 'f' this single char to search through out the newArray, instead of if f correspond the first char at newArray? also how to define it when I want uppercase letter switch only with uppercase . then if I input a String like FireFly it will return SverSyl?
Because replace doesn't change the original String. It returns a new String. You need to write
s = s.replace(newArray[i], newArray2[i]);
to assign the modified String back to the variable s.
First, strings in Java are immutable. This mean you can't change them. What you can is create a new one. Second, you compare your string with the translation array to find a match at the same index. It's very difficult to find a match at the same positions and it's not what you want.
You could use the following method:
public static String encode(String s) {
StringBuffer b = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M')) {
b.append((char) ((int) c + 13));
continue;
}
if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z')) {
b.append((char) ((int) c - 13));
continue;
}
b.append(c);
}
return b.toString();
}
The idea is that you translate each character independently and add it to a string buffer. Then you return the resulting string. To transform a character between 'a' and 'm' you just add 13 to its integer code. To transform a character between 'n' and 'z' you just remove 13 from its integer code. You do the same thing for the capital letters.
When we call this method with "FireFly you were cancelled too soon"
public static void main(String args[]) {
System.out.println(encode("FireFly you were cancelled too soon"));
}
the result is:
SverSyl lbh jrer pnapryyrq gbb fbba
Strings are immutable. So technically you need to create a new object and assign it a reference. You can assign your previous string itself to it:
s = s.replace(newArray[i], newArray2[i]);
At the end of your code you are returning s but it's value has not actually been changed. You need to assign something else to that variable or else you will get the same value you input as the output.