Java method argument in calling and caller methods - java

Just simple reverse string method.
FYI, correct methods are reverseString1 and reverseString2,
but revereStirng3() doesn't give me correct output.
I think this is because of method args and return values are stored in the Stack and related with this concept. But I don't clearly understand why revereStirng3() doesn't work correctly.
Please let me know whey this is not working.
This is what I understand, and please correct me if I'm wrong.
1. main() calls revereStirng3(A) where this passing argument array A is stored in the stack frame for the main().
revereStirng3(char[] A) where this passed argument array A is stored in revereStirng3's method frame which means main's A[] is copied to revereStirng3's stack frame's method argument A[].
After reverse, revereStirng3 creates new String(A) for return String.
Then, I thought, in the main, returned new String(A) is correctly print reversed string, but actually not.
// Given a string "abcdef", reverse it. so output should be "fedcba"
import java.util.*;
public class ReverseString {
static String revereStirng3(char[] A) {
int n = A.length;
for(int i=0; i<n/2; i++) {
char temp = A[n-i-1];
A[n-i-1] = A[i];
A[i] = temp;
}
return new String(A);
}
static void revereStirng1(char[] A) {
int n = A.length;
for(int i=0; i<n/2; i++) {
char temp = A[n-i-1];
A[n-i-1] = A[i];
A[i] = temp;
}
}
static String revereStirng2(String str) {
char[] A = str.toCharArray();
int n = A.length;
for(int i=0; i<n/2; i++) {
char temp = A[n-i-1];
A[n-i-1] = A[i];
A[i] = temp;
}
return String.valueOf(A);
}
public static void main(String[] args) {
String s = "abcdef";
char[] A = s.toCharArray();
System.out.print( revereStirng3(A) + "\n" ); **// print out "abcdef"**
System.out.println( "" );
revereStirng1(A); // print out "fedcba"
for(int i=0; i<A.length; i++)
System.out.print( A[i] );
System.out.println( "" );
System.out.print( revereStirng2(s) + "\n" ); // print out "fedcba"
System.out.println( "" );
}
}

Ok, given that zenbeni has got the real results, here is what is happening.
An array in Java is an object, so in revereString1 and revereString3 you get a copy of the reference to the array. So, your changes modify the original array, which (after the first method execution) has been reversed. Of course, the second execution reverses it again, so you get the reverse of the reverse, which is the original String.
Try using a new, locally defined array to create the reversed String and everything will work fine.

From apache commons:
StringUtil.reverse(str);

I have copied your method and executed it
System.out.println(revereStirng3("abcdef".toCharArray()));
on the result was
fedcba.
The problem is located in the main function:
public static void main(String[] args) {
String s = "abcdef";
char[] A = s.toCharArray();
System.out.println( revereStirng3(A)); // print out "abcdef"**
revereStirng1(A);
System.out.print(Arrays.toString(A)); // print out "fedcba"
System.out.println(revereStirng2(s)); // print out "fedcba"
}
Your comments do not show the true.
The valid output for it would be
fedcba
[a,b,c,d,e,f]
fedcba
And this is because you operate on the same array for three test cases. In the second step you pass allready reversed array as input. This results that the order has not changed.

Related

How to display the total length of strings in a string array?

My code:
public class array3 {
/**
* #param args
*/
public static void main(String[] args) {
String[] names = {"Einstein", "Newton", "Copernicus", "Kepler"};
for(int i = 0; i < names.length; i++){
System.out.println(names[i]);
}
}
}
I need to write a code that displays the total length of all the strings in the array I have declared(names). The only thing that comes in my mind for now is to use "names.length" but this will only give the number of elements in the String, not the actual length of the Strings.
Simply put, It can be done by:
int s=0; // A variable to store the length
for(int i = 0; i < names.length; i++){
s+=names[i].length(); // add length of each String
}
System.out.println(s); // Print `s`.
If you are using Java 8+, you might use Stream.mapToInt(ToIntFunction<? super T>) and IntStream.sum() like
String[] names = { "Einstein", "Newton", "Copernicus", "Kepler" };
System.out.println(Stream.of(names).mapToInt(String::length).sum());
If you want the length of each String you might use a lambda to display the String and its' length like
Stream.of(names).forEach(s -> System.out.printf("%s %d%n", s, s.length()));

Sorting Strings as inserted into array in Java

I'm trying to create a program that takes user input and sorts it alphabetically as it comes in using compareTo String operations (not array.sort) and prints the final sorted array at the end. I've got most of the body of this problem down but am lost once I get to the sort function. Does anyone have any ideas on how I might be able to finish out the SortInsert method?
import java.util.*;
public class SortAsInserted {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int array_size = GetArraySize();
String[] myArray = new String[array_size];
for (int i = 0; i < array_size; i++){
String nextString = GetNextString();
String[] sortedArray = SortInsert(nextString, myArray);
}
PrintArray(sortedArray);
}
input.close();
}
}
public static String[] SortInsert(String nextString, String[] myArray){
for(int i = 0; i < myArray.length;)
if (nextString.compareToIgnoreCase(myArray[i]) > 0) {
i++;
//if current text is less(alphabetically) than position in Array
}else if (nextString.compareToIgnoreCase(myArray[i]) < 0){
}
}
public static int GetArraySize(){
Scanner input = new Scanner(System.in);
System.out.print("How many items are you entering?: ");
int items_in_array = input.nextInt();
return items_in_array;
}
public static void PrintArray(String[] x) {
for (int i = 0; i < x.length; i++){
System.out.print(x[i]);
}
}
public static String GetNextString(){
Scanner input = new Scanner(System.in);
System.out.println("Enter the next string: ");
String next_string = input.nextLine();
return next_string;
}
}
There are a number of problems with this code. First I'll answer your immediate question, then enumerate some of the other problems.
The SortInsert method takes a String[] that will have been initialized with null values, so you will need to take that into account. The for loop would look something like this. (I'm using comments instead of writing the actual code since I'm not doing the project)
for (int i=0; i<myArray.length; ++i) {
if (myArray[i] == null) {
// we found a blank spot. use it to hold nextString.
break;
} else if (nexString.compareToIgnoreCase(myArray[i]) < 0) {
// nextString should be in spot i, so make room for it
// by shuffling along whatever is in the array at "i" and later
// by one place, then put nextString into position "i"
break;
}
// otherwise we'll just move to the next position to check
}
Now for the other issues.
You have a Scanner object in main that is never used. There's no point in having it and closing it at the end if your other methods make their own.
myArray will always be the sorted array so there's no point in making a local variable called sortedArray and return it from SortInsert. Note that your attempt to print sortedArray would fail anyway because that local variable is only in scope within the for loop.
When printing it should be myArray being passed to PrintArray.
If you're going to sort as you go, the TreeMap data structure is what you should be using, not an array. However, if you want to sort as you go with an array, you need to add some lines into your else if clause in SortInsert (should be sortInsert, BTW). (Another question: why is it else if rather than just else?)
The lines should create a new array of size one greater than the existing array, copy the first i-1 elements of the old array to the new array, put the new element in position i, then copy the remaining elements of the old array into positions one greater in the new array.
Once you find the position you wish to insert at, you have to shift all of the following elements down by one. Something like the following:
String temp = array[position];
for (int j = position+1; j < array_size-1; j++) {
String temp2 = array[j];
array[j] = temp;
temp = temp2;
}
array[array_size-1] = temp;

Position method to use with countletters method.

I have updated my code with two methods to use instead of the previous one. But I'm still stuck and don't know How can I create and call a method that will replace Character.isLetter(s.charAt(i)). This method is suppose to receive a char, and return a int to be used with the countLetter() method.
The methods are:
int [] countLetters (string s), int pos(char x), and void printResults(int[] counts)
And yes, the int [] countLetters does need to return an array. I'm just wondering how to get the pos method to work instead of the character.isLetter.
Here is what I got so far:
import java.util.Scanner;
public class CharCount {
public static Scanner kbd = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Enter a string: ");
printResults(null);
}
/*
* This method counts the number of occurrences in the inputed
* string and returns the array with the count.
*/
public static int[] countletters(String s){
int[] counts = new int[26];
for(int i = 0; i < s.length(); i++){
if (Character.isLetter(s.charAt(i))){
counts[(int)s.charAt(i) - 'a']++;
}
}
return counts;
}
public static int pos(char x){
return (int)charAt();
}
private static int charAt() {
// TODO Auto-generated method stub
return 0;
}
/*
* This method prints the results of the string count
*/
public static void printResults(int[] counts){
String s = kbd.nextLine();
counts = countletters(s.toLowerCase());
System.out.println("\nLetter frequencies:");
for (int i =0; i < counts.length; i++){
if (counts[i] != 0){
System.out.println((char)('a' + i) + " - " + counts[i] );
}
}
}
}
I feel like I need to start with counts[(int)s.charAt(i) - 'a']++ and move it to the print method.
Thanks.
I won't post code for you, as this is homework, but your pos method should return the relative position of the char in the alphabet. So 'a' would return 0, 'b' returns 1, 'c' returns 2,...
Myself, I'd change the char upper case or lower case, your choice, then subtract a number (or actually a char) from it, and return it.
Then the pos(...) method will be used in the countletters(...) method inside of the for loop to determine which array index to increment. Note that you should discared your charAt() method since it serves no purpose other than to confuse.

Null pointer exception that wasn't expected

Can anyone tell me why I am getting a null pointer exception here? I examined the code and haven't found anywhere that might be doing that, I'm a little stumped. Any help would be appreciated :D.
And by the way, the method is supposed to split strings between specified characters, for example: substringChars("sectionA; sectionB; sectionC;", ';'); would split the string between each semicolon (the specified character to split between) and return a string array with "sectionA" "sectonB" and "sectionC"
Code:
package substringChars;
public class SubstringChars {
public static void main(String[] args) {
substringChars("sectionA; sectionB; sectionC;", ';'); //There is an error on this line
System.out.println(SubstringChars.output[0] + SubstringChars.output[1] + SubstringChars.output[2]);
}
public static String[] output;
public static void substringChars(String iString, char sChar) {
int pChar = 0, outputSlot = 0;
char selectedChar;
for(int i = 0; i <= iString.length(); i++) {
selectedChar = iString.charAt(i);
if(selectedChar == sChar) {
if(i != iString.length()) {
SubstringChars.output[outputSlot] = (iString.substring(pChar, i)); //There is an error on this line
}
if(i == iString.length()) {
SubstringChars.output[outputSlot] = (String)(iString.substring(pChar));
}
pChar = i;
outputSlot++;
}
}
}
}
Error:
Exception in thread "main" java.lang.NullPointerException
at substringChars.SubstringChars.substringChars(SubstringChars.java:16)
at substringChars.SubstringChars.main(SubstringChars.java:5)
Thank you for your help!
Your output array is never initialized.
Your for loop is counting past the bounds of 'iString'.
At the beginning of your substringChars method, add this:
output = new String[3];
And change your for loop to use < instead of <=.
for(int i = 0; i < iString.length(); i++) {
Also, I would recommend using a Vector while generating the list first, and then convert to a normal array after.
http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
There is a function in String called split(String regex) that does the same thing you are trying to do. you should use this unless you are for some reaosn trying to re-code the wheel.
String str = "hello;my;name;is;saigon"
String a[] = str.split(";")
// a[0] = "hello"
// a[1] = "my"
// a[2] = "name"
// ...
You are using uninitialized variable!
You have
public static String[] output;
which is never uninitialized and when you try to use it to store array, it is working with null (non-existent object).
This creates array of String for up to 1000 strings and store reference in variable output :
public static String[] output = new String[1000];
Your Array output is null, since you have not initialized it,
Instead of
public static String[] output;
do
public static String[] output = new String[3];

My program is not computing the right output, and I'm not sure why

I've been staring at this program for hours, maybe a second perspective could help.
import java.util.Arrays;
import java.util.Random;
public class Examples
{
private int numbers[];
private String result;
public Examples()
{
numbers = new int[10];
Arrays.fill(numbers, 42);
}
public Examples(int[] array)
{
numbers = Arrays.copyOf(array, array.length);
}
public void setNumbers (int numbers)
{
this.numbers = new int[numbers];
}
public int [] getNumbers()
{
return numbers;
}
public String toString()
{
String result = new String();
int i;
for (i = 0; i < numbers.length; i++)
result = numbers + "\t";
return result;
}
I'm supposed to create a class that stores integer and then prints out a certain output depending on what static void main method I am provided with. The one I am currently on is,
{
public static void main( String [] args )
{
int i;
FunkyNumbers funNumbers, moreFun;
System.out.println("FunkyClientA:");
System.out.println("Test default constructor and toString method");
System.out.println();
funNumbers = new FunkyNumbers();
System.out.println("toString result from funNumbers:");
System.out.println( funNumbers.toString() );
System.out.println();
moreFun = new FunkyNumbers();
System.out.println("toString result from moreFun:");
System.out.println( moreFun.toString() );
} // end of method main
} //
The result is supposed to be
Test default constructor and toString method
toString result from funNumbers:
42 42 42 42 42 42 42 42 42 42
toString result from moreFun:
42 42 42 42 42 42 42 42 42 42
however I get,
Test default constructor and toString method
toString result from funNumbers:
[I#6e1408
toString result from moreFun:
[I#e53108
Issue: You are always assigning a new value to result and not appending.
Better to use StringBuilder as :
StringBuilder result = new StringBuilder();
for (int i = 0; i < numbers.length; i++)
result.append(numbers + "\t");
return result.toString();
If don't want to use StringBuilder then
String result = new String();
for (int i = 0; i < numbers.length; i++)
result = result + numbers + "\t";//append in result
return result;
Also make sure the method is available in FunkyNumbers class. If not accessible there, then move/copy there.
try
result += numbers[i] + "\t";
in your ToString() method
Include the code to your FunkyNumbers class and i might be able to provide better feedback.
An array in java is an object. So the variable funNumbers has as value not the array but a reference which points to the address in your memory where the array is located. When you use toString() you print this memory address on your screen and not the array as a String. You should use a StringBuffer instead to "convert" the array to a String.
private static String convertArrayToString(int[] a) {
StringBuffer sb = new StringBuffer();
for(int i=0; i<a.length; i++)
sb.append(a[i]);
return sb.toString();
}
You can also use Arrays.toString(arg) to "convert" your array to a String. As argument you give your array and you get a String representation of your array back. If your array is multidimensional use Arrays.deepToString(arg) instead.

Categories