How should I write this Java function recursively? - java

I'm trying to write the Java code below recursively:
public static int count(String word) {
int numValue = 0;
int length = word.length();
for(int i=0; i<length; i++){
String alpha = "abcdefghijklmnopqrstuvwxyz";
String letter = (word.substring(0 + i,1 + i));
numValue = numValue + alpha.indexOf(letter) + 1;
}
return numValue;
}
public static void main(String[] args) {
System.out.println(count("abc"));
}
The function returns the sum of the index of each letter in the input string parameter.
I'm attempting to write this same code recuersively, can anyone point out where I've gone wrong?
public static int count(int numValue, int i, String word) {
String alpha = "abcdefghijklmnopqrstuvwxyz";
if( i >= word.length()){
return numValue;
}
else{
String letter = (word.substring(0 + i,1 + i));
numValue = numValue + alpha.indexOf(letter) + 1;
count(numValue, i=i+1, word);
}
return numValue;
}
public static void main(String[] args) {
System.out.println(count(0,0, "abc"));
}

A simpler way would be just shrink the string again and again.
public static int count(String word) {
if (word.isEmpty()) {
return 0;
}
final String alpha = "abcdefghijklmnopqrstuvwxyz";
return alpha.indexOf(word.charAt(0)) + count(word.substring(1));
}

To change this function to be recursive, you would ideally use divide and conquer approach which is rather easy to implement. I will present it in a simple and verbose way so that you can see the steps clearly.
public static int count(String word) {
int numValue = 0;
int length = word.length();
if(length > 1)
{
String substring1 = word.substring(0, length/2);
String substring2 = word.subtring(length/2 + 1, length);
numValue += count(substring1);
numValue += count(substring2);
return numValue;
}
else
{
String alpha = "abcdefghijklmnopqrstuvwxyz";
return alpha.indexOf(word) + 1;
}
}
public static void main(String[] args) {
System.out.println(count("abc"));
}
I suppose you are doing this as an exercise to teach yourself recursiveness - if not, you may want to think whether it is not better for you to just use the iterative approach instead of recursiveness.

The variable numValue is of type int. So it doesnt get changed in the calling method, wenn you pass it to another method and change it in there. This means, the line count(numValue, i=i+1, word); basically does nothing.
You can correct the method by returning the result of the recursive call (Since you return in the if, else is not needed):
public static int count(int numValue, int i, String word) {
String alpha = "abcdefghijklmnopqrstuvwxyz";
if( i >= word.length()){
return numValue;
}
String letter = (word.substring(0 + i,1 + i));
numValue = numValue + alpha.indexOf(letter) + 1;
return count(numValue, i=i+1, word);
}
This is the reason, why your function does not work properly. The answer provided by timrau is a nicer solution for the recursion.

Related

How do you print the highest and smallest number of ASCII value in string java

I found it, thank u mate. I actually too confuse yesterday, till i forget everything that i learnt. So here is my code, what do you think?
I just don't know why my minChar not working when i delete this code :
if(stringValue.charAt(i) != 32){
public class MyString {
public static void main(String[] args) {
String stringValue = "Hello World";
SearchMyString str = new SearchMyString(stringValue);
str.stringInfo();
}
}
class SearchMyString{
private char maxChar;
private char minChar;
String stringValue;
int ascii;
public SearchMyString(String stringValue){
this.stringValue = stringValue;
}
char getMinChar(String stringValue, int n){
minChar = 'z';
for(int i = 0;i<n-1;i++){
if(stringValue.charAt(i)<minChar){
if(stringValue.charAt(i) != 32){
minChar = stringValue.charAt(i);
ascii = (int)stringValue.charAt(i);
}
}
}
return minChar;
}
public void stringInfo(){
int size = stringValue.length();
System.out.println("Smallest char : "+getMinChar(stringValue,size) + "\tASCII : " + ascii);
}
}
Use this method:
public static char getMaxChar(String a){
char max = a.charAt(0);
for (int i=0; i<a.length(); i++){
if ((a.charAt(i) > max)){
max = a.charAt(i);
}
}
return max;
}
Test case:
ACBDEFG
Returns
G
So what did we change?
For starters, if we are trying to get the character in the String that has the highest char int value, we don't need n. We are looping through the String, so all we need is the length, which can already be supplied by the .length() method.
To call the method, just do:
SearchMyString search = new SearchMyString();
search.getMaxChar(nama);
EDIT: So to make the method more reliable, instead of automatically setting max to 'A', we can set it to the first char of a (e.g, a.charAt(0))

counter for string search in another string

I want to search how many times a string appear in another string
It does not work correctly when i put an similar string at the end.
public class C3_Project3_WPr {
public static void main(String[] args) {
String strn1="AliAliAli";
String strn2="AliAliSinaAli";
String strn3="Ali";
int count1=StringCounter(strn1, strn3);
System.out.println(count1);
int count2=StringCounter(strn2, strn3);
System.out.println(count2);
}
//ُString in String Method
static int StringCounter(String str1, String str2){
int counter=0;
if (str1.isEmpty() || str2.isEmpty()) {
return 0;
}
for(int i= 0; i<str1.length(); i++){
if(str1.contains(str2)){
counter++;
str1= str1.substring(str2.length());
}
}
return counter;
}
}
Solution to your problem is here
public static void main(String[] args) {
String strn1 = "AliAliAliwewdwdweAli";
String strn2 = "AliAliSinaAliAlAli";
String strn3 = "Ali";
int count1 = StringCounter(strn1, strn3);
System.out.println(count1);
int count2 = StringCounter(strn2, strn3);
System.out.println(count2);
}
// ُString in String Method
static int StringCounter(String str1, String str2) {
int counter = 0;
if (str1.isEmpty() || str2.isEmpty()) {
return 0;
}
for (int i = str1.indexOf(str2); i >= 0; i = str1.indexOf(str2, i + str2.length())) {
counter++;
}
return counter;
}
}
When modifying str1 you only take in to account the length of the search string, but ignore the index in which it was found. Fixing this (e.g., by using indexOf), will fix your results too:
int index = str1.indexOf(str2);
while (index >= 0) {
counter++;
index = str1.indexOf(str2, index + str2.length());
}
Use recursive method: It's quick and easy way to solve your problem:
static int StringCounter(String str1, String str2){
return (str1.contains(str2)) ? 1 + StringCounter(str1.replaceFirst(str2, ""), str2) : 0;
}

how to use java substring on Japanese utf-8 kanji

Is it possible to use substring to extract single utf8 kanji from a string? The problem is that utf-8 "characters" can have a length of 1, 2 or 3.
For instance, length of "𨦇𨦈𥻘" is 6 so String.substring(1, 2) doesn't get the first complete character.
In PERL, I could just use substr("𨦇𨦈𥻘", 1, 1) to get the first character, or substr("𨦇𨦈𥻘", 2, 1) to get the second character.
UPDATE:
Based on #msandiford's suggestion, I came up with this.
public class SplitKanji {
private String [] splitKanji;
private SplitKanji(String string) {
int cpCount = string.codePointCount(0, string.length());
splitKanji = new String[cpCount];
int nextSlot = 0;
for (int i = 0; i < string.length();) {
int ii = string.offsetByCodePoints(i, 1);
splitKanji[nextSlot++] = string.substring(i, ii);
i = ii;
}
}
private String[] get() {
return splitKanji;
}
public static void main(String[] args) {
String startKanji = "私今日𨦇𨦈𥻘";
SplitKanji myStuff = new SplitKanji(startKanji);
String [] split = myStuff.get();
System.out.print(startKanji + "=");
for(String kanji: split)
System.out.print(kanji + ":" + kanji.length() + ", ");
System.out.println();
}
}
You can extract individual Unicode codepoints from the String like so:
public static final String KANJI = "𨦇𨦈𥻘";
public static void main(String[] args)
{
System.out.println(KANJI.length()); // 6
System.out.println(KANJI.codePointCount(0, KANJI.length()));// 3
// Loop over each code point
for (int i = 0; i < KANJI.length(); )
{
System.out.println(KANJI.codePointAt(i));
i = KANJI.offsetByCodePoints(i, 1);
}
// Extract the third codepoint
int indexForThirdCodePoint = KANJI.offsetByCodePoints(0, 2);
int thirdCodePoint = KANJI.codePointAt(indexForThirdCodePoint);
System.out.println(thirdCodePoint);
// Convert codepoint back to string
System.out.println(new String(Character.toChars(thirdCodePoint)));
}
You could use the above techniques to obtain the start and end index of the codepoint that you require, and then use substring(start, end) to extract.
(edit) All of this could be simplified with a bit of judicious refactoring and utility functions. Below is one possible example; I don't know the use case for your code is, so it's a bit hard to know what would be best for you.
public static final String KANJI = "𨦇𨦈𥻘";
public static int lengthCodepoints(String s)
{
return s.codePointCount(0, s.length());
}
public static String substringCodepoint(String s, int startCodepoint, int numCodepoints)
{
int startIndex = s.offsetByCodePoints(0, startCodepoint);
int endIndex = s.offsetByCodePoints(startIndex, numCodepoints);
return s.substring(startIndex, endIndex);
}
public static void main(String[] args)
{
int cpLength = lengthCodepoints(KANJI);
for (int i = 0; i < cpLength; ++i)
{
System.out.println(substringCodepoint(KANJI, i, 1));
}
}

Converting a number to binary java code

I am writing a code to convert a number to binary representation.Here's my code.It doesn't give the correct answer but I can't figure out where I am making the mistake.If someone could point out where my mistake and how to correct it I would be grateful.
public class ConvertBinary{
public static String convertBinary(int n){
String s="";
while(n>0){
s+=(n%2);
n=n/2;
}
int len=s.length();
String[] binary=s.split("");
String[] binaryCopy=new String[s.length()];
for(int i=0;i<len;i++){
binaryCopy[i]=binary[len-i-1];
s+=binaryCopy[i];
}
return s;
}
public static void main (String args[]){
System.out.println(convertBinary(19));
}
}
Apart from all these answers the problem with your code was that you are not clearing the string before reversing it. So before the for loop just put s = "" and you code should work fine.. :)
Based on comment
public class ConvertBinary {
public static String convertBinary(int n) {
String s = "";
while (n > 0) {
s += (n % 2);
n = n / 2;
}
int len = s.length();
String[] binary = s.split("");
String[] binaryCopy = new String[s.length()];
s = "";
for (int i = 0; i < len; i++) {
binaryCopy[i] = binary[len - i - 1];
s += binaryCopy[i];
}
return s;
}
public static void main(String args[]) {
int num = 4;
System.out.println(convertBinary(num));
System.out.println(Integer.toBinaryString(num));
}
}
public static String convertBinary(int n){
String s="";
while(n>0){
s+=(n%2);
n=n/2;
}
return (new StringBuffer(s).reverse().toString());
}
If you're looking for error in your implementation, you'd rather put:
s = (n % 2) + s;
isntead of
s+=(n%2);
so the code'll be
// n should be positive
public static String convertBinary(int n){
if (n == 0)
return "0";
String s = "";
// for is more compact than while here
for (; n > 0; n /= 2)
s = (n % 2) + s;
return s;
}
however in real life
Integer.toString(n, 2);
is much more convenient
Use Java standard library: http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toString%28int,%20int%29
public class ConvertBinary{
public static String convertBinary(int n){
return Integer.toString(n, 2);
}
public static void main (String args[]){
System.out.println(ConveryBinary.convertBinary(19));
}
}
EDIT: As #Holger says, there's also a toBinaryString: http://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#toBinaryString%28int%29
public static String convertBinary(int n){
return Integer.toBinaryString(n);
}

permute a string

Given the String, print all its permutations. To do that, i came up with the following program.
public static char[] swap(char[] input, int i, int j) {
char temp;
temp = input[i];
input[i] = input[j];
input[j] = temp;
return input;
}
/**
*
* #param args
*/
public static void permuteStrings(char[] inputString, int start, int finish ) {
//Base case: When there is only single element, print the string
if(start == finish)
System.out.println(inputString);
else {
//Recursive case: Swap first element with all the elements and permute on the
// rest of string.
for(int i = start; i <= finish; i++) {
inputString = swap(inputString, start, i);
permuteStrings(inputString, i + 1, finish);
inputString = swap(inputString,start, i); //restoring the original string
}
}
}
But, for the given input ABC, all it prints are
ABC
BAC
I cant seem to figure out what the problem is
Figured out the problem. The problem was in the function invocation:
permuteStrings(inputString, i + 1, finish);.
The correct way was:
permuteStrings(inputString, start + 1, finish);
Use recursion
public static void permutation(String str)
{
permutation("", str);
}
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0)
System.out.println(prefix);
else
{
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}

Categories

Resources