String Array class in JAVA - java

I need help with this code
Problem
Write a Java class having a String array, with global visibility.
Add a method that adds a given sting to the string array.
Add a method that searches for a given string in the string array.
Add a method that searches for a given character in the string array. The method should count and returns the occurrence of the given character.
Write an appropriate main method to test these class methods.
and this is the code. First, I created a class for method I create scound class for TestString array
my question is i have error in scound class ,and i try to fix it but it dose not work
this the first class:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package ooplab3;
public class StringArray {
String[] sTA = null;
int index = 0; //last added sring position in the string array
public StringArray() {
}
public String[] getsTA() {
return sTA;
}
public String getsTAindex(int i) {
return sTA[i];
}
public int getcounter() {
return index;
}
public void setCounter(int counter) {
this.index = counter;
}
public void addStrinToArray(String st) {
if (this.index < sTA.length) {
sTA[this.index] = st;
this.index++;
}
}
public int searchStringInArray(String sT) {
int n = 0;
for (int i = 0; i < this.index; i++) {
for (int j = 0; j < 10; j++) {
int indexOf = sTA[i].indexOf(sT);
n += searchStringInArray(sTA[i]);
return n;
}
}
return n;
}
public int searchcharInArray(String sT) {
int n = 0;
int Startindex = 0;
do {
n += sT.indexOf(Startindex);
} while (n > Startindex);
return n;
}
public boolean containsChar(String s, char search) {
if (s.length() == 0) {
return false;
} else {
return s.charAt(0) == search || containsChar(s.substring(1), search);
}
}
public void containsChar(Object object, String search) {
}
}
Sound class :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package ooplab3;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;
public class testStringarray {
public static void main(String[] args) throws FileNotFoundException {
String[] testArray = new String[30];
Scanner infile = new Scanner(new FileReader("input_txt"));
// System.out.println("contents of testArray");
int i = 0;
while (infile.hasNext()) {
String j = infile.next();
addString(j, i);
System.out.println(testArray[i] + "\n");
i++;
}
}
}
the input file contain: hello this is my java program

As near as I can tell, you have a class named StringArray, and a second class which is intended to test the capabilities of StringArray. But that second class doesn't actually use StringArray at all; instead, it creates its own array, and calls a method addString() which has a similar, but not identical, name as a method in StringArray.
One significant problem with StringArray is that it never creates an actual array -- its array member variable remains null. You need a "new" expression to create the actual array. Then your test class should be doing something like
StringArray sa = new StringArray();
sa.addStringToArray("Hello, world");
String[] array = sa.getsTA();
for (String s: array)
System.out.println(s);

A number of problems exist.
Here's one of them:
In your StringArray.addStrinToArray() method, you attempt to assign a string to an element of a null array:
String[] sTA = null;
sTA[index] = st; //this will throw NullPointerException
You need to initialise the array:
String[] sTA = new String[initialSize];
Where initialSize is an integer containing the initial size of the array.

Related

Copy Constructor for a String Array in Java

So I'm currently working on a project that is recreating methods for Array String Lists and Linked String Lists. There is a StringList interface, that both ArrayStringList and LinkedStringList implement. We are not allowed to see the source code for the interface - only the API documentation. For each class, we have to create a default constructor and copy constructor for both classes. I've ran tests, and the default constructors both pass but the ArrayStringList copy constructor does not work and has been throwing the error message of "null" or "-1". I am pretty new to inheritance and interfaces, and I think the object parameters vs string array data types are throwing me off a bit.
Here is the code I have so far, and the methods used in the constructor:
My Copy Constructor:
private String[] stringArray;
private int size;
public ArrayStringList(StringList sl) {
size = sl.size();
ArrayStringList asl = new ArrayStringList();
for(int i = 0; i < size-1; i++) {
if(sl.get(i) != null) {
asl.set(i,sl.get(i).toString());
} //if
} // for
} // copy constructor
Size Method:
public int size() {
return stringArray.length;
} // size
Get Method:
public String get(int index) {
if(index < 0 || index >= size) {
throw new IndexOutOfBoundsException("out of bounds");
} else {
return stringArray[index];
}
} //get
Set Method:
public String set(int index, String s) {
String old = stringArray[index];
stringArray[index] = s;
return old;
} // set
In the project, the description of the copy constructor was as follows:
The implementing class must explicitly define a copy constructor. The copy constructor should take exactly one parameter of the interface type StringList. It should make the newly constructed list object a deep copy of the list referred to by the constructor's parameter. Therefore, the initial size and string elements of the new list object will be the same as the other list. To be clear, the other list can be an object of any implementation of the StringList interface. No other assumptions about the type of the object should be made.
public class ArrayStringList implements StringList {
private static final int INITIAL_CAPACITY = 10;
private String[] stringArray;
private int size;
public ArrayStringList(StringList sl) {
stringArray = sl.toArray();
size = stringArray.length;
}
public ArrayStringList() {
stringArray = new String[INITIAL_CAPACITY];
size = 0;
}
// TODO: Extract 'if-cascade' to an validate(..) method
#Override
public String set(int index, String s) {
if (index >= size) {
throw new IndexOutOfBoundsException("")
} else if (s == null) {
throw new NullPointerException("the specified string is null");
} else if (s.isEmpty()) {
throw new IllegalArgumentException("specified string is empty");
}
String old = stringArray[index];
stringArray[index] = s;
return old;
}
// TODO: Check if posible to extend the stringArray
#Override
public boolean add(String s) {
if (s == null) {
throw new NullPointerException("the specified string is null");
} else if (s.isEmpty()) {
throw new IllegalArgumentException("specified string is empty");
}
if (size == stringArray.length) {
int newListCapacity = stringArray.length * 2;
stringArray = Arrays.copyOf(stringArray, newListCapacity);
}
stringArray[++size] = s;
return true;
}
// TODO: implement other methods ...
}
Keep in mind that this implementation is still buggy, but you can use it as a starting point
public void ArrayStringList(StringList sl) {
size = sl.size();
ArrayStringList asl = new ArrayStringList();
for(int i = 0; i < size; i++) {
if(sl.get(i) != null) {
String s = asl.set(i,sl.get(i).toString());
System.out.println(s);
} //if
} // for
}
Change set method like below. And call it by the help of class object. it will set value in global static list.
//Change set method like this
public String set(int index, String s) {
stringArray[index] = s;
return stringArray[index];
}
I would initialise the internal array to the value of size and also make use of the fact that the String class also has a copy-constructor
public ArrayStringList(StringList sl) {
this.size = sl.size();
this.stringArray = new String[size];
for(int j = 0; j < size; j++) {
this.stringArray[j] = new String(sl.get(i));
}
}

Static method that takes an array of strings and returns an integer

I am still pretty new to programming and I am trying to do this small program where I write a static method that takes an array of strings and returns an integer. From there I have to find the index position of the smallest/shortest string and return that index value. I am completely lost and struggling with this. Can I get some help?
My code so far...
public class test
{
public static void main(String [] args)
{
String [] Month = {"July", "August", "September", "October"};
smallest(Month);
System.out.println("The shortest word is " + smallest(Month));
}
public static String smallest(String Month[])
{
String first = Month[0];
for (int i = 1 ; i < Month.length ; i++)
{
if (Month[i].length()<first.length())
{
first = Month[i];
}
}
return first;
}
}
Check the code below,
public class Test {
public static void main(String [] args)
{
String [] month = {"July", "August", "September", "October"};
// smallest(Month);
System.out.println("The shortest word index position is " + smallest(month));
}
public static int smallest(String Month[])
{
String first = Month[0];
int position=0;
for (int i = 1 ; i < Month.length ; i++)
{
if (Month[i].length()<first.length())
{
first = Month[i];
position=i;
}
}
return position;
}
}
Your code is actually pretty close, but --if I understand your task correctly-- instead of the actual smallest element, you should keep track of the index only, since that is what you want to return in the end.
public static int smallest(String[] months) {
int first = 0;
for (int i = 1; i < months.length; i++) {
if (months[i].length() < months[first].length()) {
first = i;
}
}
return first;
}
Focusing on the smallest method.
public static void smallest(String[] month) {
// since we have no knowledge about the array yet, lets
// say that the currently known shortest string has
// size = largest possible int value java can store
int min_length = Integer.MAX_INT, min_length_idx = -1;
for (int i = 0; i < month.length; i++) {
// is this current string a candidate for a new minimum?
if (month[i].length() < min_length) {
// if so, lets keep track of the length so that future
// indices can be compared against it
min_length = month[i].length();
min_length_idx = i;
}
}
return min_length_idx;
}
This method will then also cover the case where the array does not have any strings in it, i.e., empty array.
public static int smallest(String month[]) {
int smallest = 0;
for ( int i=0; i<month.length; i++ {
if (...) {
smallest = i;
}
}
return smallest;
}
Note: use standard conventions where variable names begin with a lower-case letter.

Java sorting text file with Comparable

I need a program that reads in data and sorts the file in descending order using quicksort based on the index provided for instance this is the data using comparable
adviser,32/60,125,256,6000,256,16,128,198,199
amdahl,470v/7,29,8000,32000,32,8,32,269,253
amdahl,470v/7a,29,8000,32000,32,8,32,220,253
amdahl,470v/7b,29,8000,32000,32,8,32,172,253
amdahl,470v/7c,29,8000,16000,32,8,16,132,132
And i need to sort by the 5th index(mmax) case 2 and the 6th(cache) case 3 and the ninth index(php) case 4 in descending order & print the first index which is already sorted case 1
The problems with my code are as follows:
It doesn't sort based off the index
It gives me an error at runtime with the code: Arrays.sort(c);
Please help with suggestions
Thanks
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.Scanner;
public class Prog4 {
static Scanner input;
static File filename;
/**
* This function displays the menu for the user to choose an option from
*/
public void menu() {
System.out.println("Option 1: Sort by VENDOR: ");
System.out.println("Option 2: Sort decreasing number by MMAX: ");
System.out.println("Option 3: Sort decreasing number by CACH: ");
System.out.println("Option 4: Sort decreasing number by PRP: ");
System.out.println("Option 5: Quit program");
}
/**
* Constructor to handle the cases in the menu options
* #throws FileNotFoundException
* #throws IOException
*/
public Prog4() throws FileNotFoundException {
//Accepts user input
Scanner in = new Scanner(System.in);
//calls the menu method
menu();
//Initializes the run variable making the program loop until the user terminates the program
Boolean run = true;
//While loop
while (run) {
switch (in.nextInt()) {
case 1:
System.out.println("Option 1 selected");
System.out.println("Sorted by vendor:");
filename = new File("machine.txt");
//Instantiate Scanner s with f variable within parameters
//surround with try and catch to see whether the file was read or not
try {
input = new Scanner(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Instantiate a new Array of String type
String array [] = new String[10];
//while it has next ..
while (input.hasNext()) {
//Initialize variable
int i = 0;
//store each word read in array and use variable to move across array array[i] = input.next();
//print
System.out.println(array[i]);
//so we increment so we can store in the next array index
i++;
}
case 2:
System.out.println("Press any key to continue");
Scanner input2 = new Scanner(System.in);
String x = input2.nextLine();
if (x.equals(0)) continue;
System.out.println("Option 2 selected") ;
Computer[] c = new Computer[10];
filename = new File("machine.txt");
try {
input = new Scanner(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Arrays.sort(c);
while (input.hasNextLine()) {
for (int i = 0; i < c.length; i++) {
System.out.println(c[i]);
}
}
}
}
}
/**
* Main method
* #param args
* #throws FileNotFoundException
*/
public static void main(String[] args) throws FileNotFoundException {
//Calls the constructor
new Prog4();
//static Scanner input;
}
public static void quickSort(int arr[], int left, int right) {
if (left < right) {
int q = partition(arr, left, right);
quickSort(arr, left, q);
quickSort(arr, q+1, right);
}
}
private static int partition(int arr[], int left, int right) {
int x = arr[left];
int i = left - 1;
int j = right + 1;
while (true) {
i++;
while (i < right && arr[i] < x)
i++;
j--;
while (j > left && arr[j] > x)
j--;
if (i < j)
swap(arr, i, j);
else
return j;
}
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Comparator class:
import java.util.Comparator;
class Computer implements Comparable<Computer> {
private String vendor;
private int mmax;
private int cach;
private int php;
public Computer(int value) {
this.mmax = value;
}
public String getVendor() {
return vendor;
}
public void setVendor(String vendor) {
this.vendor = vendor;
}
public int getMmax() {
return mmax;
}
public void setMmax(int mmax) {
this.mmax = mmax;
}
public int getCach() {
return cach;
}
public void setCach(int cach) {
this.cach = cach;
}
public int getPhp() {
return php;
}
public void setPhp(int php){
this.php = php;
}
#Override
public int compareTo(Computer m) {
if (mmax < m.mmax) {
return -1;
}
if (mmax > m.mmax) {
return 1;
}
// only sort by height if age is equal
if (cach > m.cach) {
return -1;
}
if (cach < m.cach) {
return 1;
}
if (php > m.php) {
return -1;
}
if (php < m.php) {
return 1;
}
return 0;
}
public static Comparator<Computer> ComparemMax = new Comparator<Computer>() {
#Override
public int compare(Computer p1, Computer p2) {
return p2.getMmax() - p1.getMmax();
}
};
}
The biggest problem is that the Computer classes do not get instantiated for each line that gets read.
As you want to have different sort options depending on the user input, you can not let the Computer class determine the compare method, but instead you will need to create a separate Comparator implementation for each sort option. Next, make the file read operation generic and abstract it away in a separate method call from each selected case. Instead of an array of Computers, I would make it a List or a Set, because you don't (want to) know the length up front.
I would like to lay out the steps in detail so that you could figure out each step for yourself. You have got a lot of it right.. but there are gaps.
Create a Computer class. It should have a constructor which takes a single String and splits it using the separator ',' and parses each part to String/int as applicable. (It would be preferable for you to parse and store the whole string.. which means you can have 10 fields in your class)
Create a blank ArrayList to store the Computer objects.
Iterate through the file and readLine
Call the Computer constructor using the String representing each line in the file within the while loop
Add the new Computer object to the computers ArrayList
Write 5 different comparators.
Based on user input, instantiate the correct comparator and pass it to the sort method
Print the sorted array
If you still face a problem, mention the specific point at which you like more clarity..

Sorting using comparable

Intro
My code to do a custom sort by using Comparable is not work the way I want it to. I'm basically taking an Array of directories and sorting them by:
First number of directories, the fewer comes first.
If it's a tie alphabetically.
The problem
An example of an input you be:
["/", "/usr/", "/usr/local/", "/usr/local/bin/", "/games/",
"/games/snake/", "/homework/", "/temp/downloads/" ]
Which should return this:
["/", "/games/", "/homework/", "/usr/", "/games/snake/",
"/temp/downloads/", "/usr/local/", "/usr/local/bin/" ]
But for some reason my code is return this:
["/", "/usr/", "/games/", "/homework/", "/usr/local/",
"/games/snake/", "/usr/local/bin/", "/temp/downloads/" ]
My code [edited with comments]
import java.util.*;
public class Dirsort { public String[] sort(String[] dirs) {
//Creates Array list containing Sort object
ArrayList<Sort> mySort = new ArrayList<Sort>();
//Loop that gets the 3 needed values for sorting
for (String d: dirs){
String [] l = d.split("/");//String array for alphabetical comparison
int di = d.length();//Length of array for sorting by number of directories
mySort.add(new Sort(di,l,d));//adds Sort object to arraylist (note d (the entire directory) is needed for the toString)
}
Collections.sort(mySort);//sorts according to compareTo
String [] ans = new String [mySort.size()];//Creates a new string array that will be returned
int count = 0;//to keep track of where we are in the loop for appending
for (Sort s: mySort){
ans[count] = s.toString();
count++;
}
return ans;
}
class Sort implements Comparable<Sort>{
private int d;//number of directories
private String [] arr;//array of strings of names of directories
private String dir;//full directory as string for toString
//Constructor
public Sort(int myD, String [] myArr, String myDir){
d = myD;
arr = myArr;
dir = myDir;
}
//toString
public String toString(){
return dir;
}
#Override
public int compareTo(Sort arg0) {
// TODO Auto-generated method stub
//If they are the same return 0
if (this.equals(arg0)){
return 0;
}
//if the directories are empty
if("/".equals(arg0.dir)){
return 1;
}
if ("/".equals(this.dir)){
return -1;
}
//If they are not the same length the shorter one comes first
if (this.d != arg0.d){
return this.d - arg0.d;
}
//If they are the same length, compare them alphabetically
else{
for (int i = 0; i < arg0.d; i++){
if (!this.arr[i].equals(arg0.arr[i])){
return this.arr[i].compareTo(arg0.arr[i]);
}
}
}
return 0;
}
}
}
The bug is here:
for (String d: dirs){
String [] l = d.split("/");
int di = d.length(); // <- here
mySort.add(new Sort(di,l,d));
}
Because there you are comparing the length of the entire directory String, not the number of 'folders' in the directory. That's why "/usr/" comes before "/homework/", for example, because:
"/usr/".length() == 5
"/homework/".length() == 10
I believe what you wanted was this, using the length of the split:
int di = l.length;
Then the output is:
/
/games/
/homework/
/usr/
/games/snake/
/temp/downloads/
/usr/local/
/usr/local/bin/
There's another small bug though (possibly), which is that calling split on a String that starts with the delimiter will result in an empty String at the beginning.
IE:
"/usr/".split("/") == { "", "usr" }
So you might want to do something about that. Though here it means that all of them start with the empty String so it doesn't end up with an effect on the way you're doing the comparison.
And as a side note, it's also true what #JBNizet is suggesting that giving your variables more meaningful names helps a lot here. fullDir.length() and splitDir.length would have made this much easier to spot (and it may have never happened in the first place).
Here's a fixed version of your code, which handles the case where both directories are "/", which removes the unnecessary, and incorrectly passed length of the parts array, and which uses more meaningful variable names:
public class Dirsort {
public static void main(String[] args) {
String[] input = new String[] {
"/",
"/usr/",
"/usr/local/",
"/usr/local/bin/",
"/games/",
"/games/snake/",
"/homework/",
"/temp/downloads/"
};
String[] result = new Dirsort().sort(input);
System.out.println("result = " + Arrays.toString(result));
}
public String[] sort(String[] dirs) {
ArrayList<Sort> sorts = new ArrayList<Sort>();
for (String dir : dirs) {
String[] parts = dir.split("/");
sorts.add(new Sort(parts, dir));
}
Collections.sort(sorts);
String[] result = new String[sorts.size()];
int count = 0;
for (Sort sort: sorts) {
result[count] = sort.toString();
count++;
}
return result;
}
class Sort implements Comparable<Sort> {
private String[] parts;
private String dir;
public Sort(String[] parts, String dir) {
this.parts = parts;
this.dir = dir;
}
public String toString(){
return dir;
}
#Override
public int compareTo(Sort other) {
if (this.equals(other)){
return 0;
}
if("/".equals(other.dir) && "/".equals(dir)) {
return 0;
}
if("/".equals(other.dir)){
return 1;
}
if ("/".equals(this.dir)){
return -1;
}
if (this.parts.length != other.parts.length){
return this.parts.length - other.parts.length;
}
else {
for (int i = 0; i < other.parts.length; i++){
if (!this.parts[i].equals(other.parts[i])){
return this.parts[i].compareTo(other.parts[i]);
}
}
}
return 0;
}
}
}
I spotted the problem by simply using my debugger and make it display the value of all the variables.
public class Disort
{
public static String[] sort(String[] dirs)
{
ArrayList<Path> mySort = new ArrayList<Path>();
Path pathDir;
for(String dir : dirs){
pathDir = Paths.get(dir);
// check if directory exists
if(Files.isDirectory(pathDir)){
mySort.add(pathDir);
}
}
// sort the ArrayList according a personalized comparator
Collections.sort(mySort, new Comparator<Path>(){
#Override
public int compare(Path o1, Path o2)
{
if(o1.getNameCount() < o2.getNameCount()){
return -1;
}
else if(o1.getNameCount() > o2.getNameCount()){
return 1;
}
else{
return o1.compareTo(o2);
}
}
});
// to return a String[] but it will better to return a ArrayList<Path>
String[] result = new String[mySort.size()];
for(int i = 0; i < result.length; i++){
result[i] = mySort.get(i).toString();
}
return result;
}
}

Null pointer exception for Array of Objects

I am new to using arrays of objects but can't figure out what I am doing wrong and why I keep getting a Null pointer exception. I am trying to create an Theatre class with an array of spotlight objects that are either set to on or off. But - whenever I call on this array I get a null pointer exception.
package theatreLights;
public class TheatreSpotlightApp {
public static void main(String[] args) {
Theatre theTheatre = new Theatre(8);
System.out.println("element 5 " + theTheatre.arrayOfSpotlights[5].toString());
}
}
package theatreLights;
public class Theatre {
spotlight[] arrayOfSpotlights;
public Theatre(int N){
arrayOfSpotlights = new spotlight[N];
for (int i = 0; i < arrayOfSpotlights.length; i++) {
arrayOfSpotlights[i].turnOn();
}
}
}
package theatreLights;
public class spotlight {
int state;
public spotlight(){
state = 0;
}
public void turnOn(){
state = 1;
}
void turnOff(){
state = 0;
}
public String toString(){
String stringState = "";
if(state == 0){
stringState = "is off";
}
else if(state==1){
stringState = "is on";
}
return stringState;
}
}
I must be doing something basic wrong in creating the array but can't figure it out.
replace
arrayOfSpotlights[i].turnOn();
with
arrayOfSpotLights[i] = new Spotlight();
arrayOfSpotlights[i].turnOn();
The line
arrayOfSpotlights = new spotlight[N];
will create an array of spotlights. It will however not populate this array with spotlights.
When you do "arrayOfSpotlights = new spotlight[N];" you init an array of length N, what you need to do is also init each object in it:
for i=0; i<N; i++
arrayOfSpotlights[i] = new spotlight();
arrayOfSpotlights[i].turnOn();
Hope I'm correct :)
You are not creating an spotlight objects.
arrayOfSpotlights = new spotlight[N];
This just creates an array of references to spotlights, not the objects which are referenced.
The simple solution is
for (int i = 0; i < arrayOfSpotlights.length; i++) {
arrayOfSpotlights[i] = new spotlight();
arrayOfSpotlights[i].turnOn();
}
BTW You should use TitleCase for class names.
You could write your class like this, without using cryptic code like 0 and 1
public class Spotlight {
private String state;
public Spotlight() {
turnOff();
}
public void turnOn() {
state = "on";
}
void turnOff() {
state = "off";
}
public String toString() {
return "is " + state;
}
}
You declared the array arrayOfSpotlights, but didn't initialize the members of the array (so they are null - and you get the exception).
Change it to:
public class Theatre {
spotlight[] arrayOfSpotlights;
public Theatre(int N){
arrayOfSpotlights = new spotlight[N];
for (int i = 0; i < arrayOfSpotlights.length; i++) {
arrayOfSpotlights[i]=new spotlight();
arrayOfSpotlights[i].turnOn();
}
}
}
and it should work.

Categories