Hello I have implemented this basic program which should sort out the strings that are inserted however it somehow is failing to insert the strings .
For example if I implement :
TestSort t = new TestSort();
t.i("abc");
t.i("aab");
Can anybody see the error and help me fix this error please ?
Thank you
Here is the code :
public class TestSort {
private int length;
String[] data;
public TestSort() {
length = 0;
}
public void i(String value) {
data[length] = value;
setSorted(data);
length++;
}
public void setSorted(String data[]) {
for(int i = data.length-1; i >= 0; i--) {
for(int j = 0; j < i; j++) {
if(data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
for(int i = 0; i < data.length; i++) {
System.out.print(data[i] +" ");
}
}
}
You don't initialize the array data. So it is set null, and accesses with data[i] will get you an NullPointerException. Even if you initialize this field, it will not work, as Arrays in Java have a fixed size, you have to reallocate the Array, if you insert a new value. You should try a List-implementation instead.
So the code should initialize in the constructor:
data = new ArrayList<String>();
and insertion would change to
data.add(value);
you can change your constructor code as (String array max length can be taken as input parameter):
public testsort()
{
data = new String[10];
length = 0;
}
But if you are not sure with the size of array you can use ArrayList.
You are getting exception because you are comparing with data[j+1] that is still null.
first time when you call
t.i("abc");
there is only one reference in data array that is pointing to String literal "abc" and that is at index 0. index 1 is still referring to null.
first String is already sorted so no need to sort that. if you are having more than one string then you should call setSorted() method.
to solve this you can put your condition in loop as:
if((data[j] != null && data[j+1] != null) &&(data[j].compareTo(data[j + 1]) > -1))
A working example but still: use a List and life is much easier :-)
public class Test {
private int length;
private String[] data;
public Test(int arrayLength) {
// INITIALIZE YOU ARRAY --> No NULLPOINTEREXCEPTION!
data = new String[arrayLength];
length = 0;
}
public void i(String value) {
data[length] = value;
length++;
}
public void setSorted() {
for (int j = 0; j < data.length - 1; j++) {
if (data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
for (String s : data) {
System.out.println(s);
}
}
public static void main(String[] args) {
Test t = new Test(5);
t.i("bbb");
t.i("aaa");
t.i("ccc");
t.i("zzz");
t.i("ddd");
// USE SETSORTED HERE --> else you fill your array with the same elements
t.setSorted();
}
}
The variable 'data' is null since it is nowhere initialized hence giving null pointer exception. Since 'data' is an array and as per the rule whenever an array is defined, it has to be of defined length. for e.g if we consider your case. 'data' can be initialized as :-
String[] data = new String[any numerical value]
the numerical value will be its length i.e. the maximum number of elements it can hold.
Secondly, as per your program statement :-
data[length] = value;
is trying to assign value at data's [length] index which is completely wrong since you haven't defined the length therefore how could you guess the index's value. Therefore your this approaoch is logically wrong.
For such situation i.e. whenever we're unaware about the length of the array, use of ArrayList is suggested. Therefore your program can be re-written by two ways:-
1) Either define the length of the array
String[] data = new String[n];
where n ranges from at least 1 to any positive integer.
2) By using ArrayList
public class Main {
List<String> data;
public Main(){
data = new ArrayList<String>();
}
public static void main(String... q){
Main m = new Main();
m.insertData("abc");
m.insertData("zxy");
m.insertData("aab");
m.insertData("aaa");
m.showData();
}
public void insertData(String str){
data.add(str);
Collections.sort(data);
}
public void showData(){
if(data!=null && !data.isEmpty()){
for(String s : data){
System.out.println(s);
}
}
}
}
output:-
aaa
aab
abc
zxy
Hope this helps.
as Mnementh suggested, the reason for NPE is that you have created the field data of type String[] but you never initialized it.
Other answers have provided every reason on why your code throwing ugly errors; I have just improved your code by replacing your String[] with List<String> so you don't have to worry about the size of your array anymore.
Sorting is also simplified now using Collections.sort().
have a look,
class test1 {
public static void main(String[] args) {
Test sorting = new Test();
sorting.input("abc");
sorting.input("cba");
sorting.input("aab");
sorting.setSorted();
}
}
class Test {
private List<String> data = new ArrayList<String>();
public void input(String value) {data.add(value);}
public void setSorted() {
Collections.sort(data);
for (String current : data) {
System.out.println(current);
}
}
}
if you are using Java 8, then you can use Arrays.parallerSort(), it performs sorting the same way as Collection.sort but with a parallel implementation.
Current sorting implementations provided by the Java Collections Framework > (Collections.sort and Arrays.sort) all perform the
sorting operation sequentially in the calling thread. This enhancement
will offer the same set of sorting operations currently provided by
the Arrays class, but with a parallel implementation that utilizes the
Fork/Join framework. These new API's are still synchronous with regard
to the calling thread as it will not proceed past the sorting
operation until the parallel sort is complete.
to implement it, replace Collections.sort with Arrays.parallelSort in the above code,
Replace,
Collections.sort(data);
with,
Arrays.parallelSort(data.toArray(new String[data.size()]));
Related
I have an object array containing two fields per object.
I have to write a method that will sort my array by the first field.
I already have a method which extracts the first field from each object
I always get an error message when I call my method to sort.
Here is my code:
public static void trier(String[]code, String[]nom, int nbObj) {
for(int i = 0; i < nbObj-1; i++) {
int indMin = i;
for (int j = i+1; j < nbObj; j++)
if (code[j].compareTo(code[indMin]) < 0)
indMin = j;
if (indMin != i) {
// permutation :
String tempo = code[i];
code[i] = code[indMin];
code[indMin] = tempo;
// permutation :
String temp = nom[i];
nom[i] = nom[indMin];
nom[indMin] = temp;
}
}
}
and the call :
Classe.trier(tableau, tableau, nbObj);
I also tried Class.sort(array.getCode(), array.getName(), nbStudent);
But I still have compilation errors
thank you in advance for your help
First of all, you don't have to use 2 separate arrays to contain your data. You can put everything in a single array, but better way is to use Java Collections. Perfect choice is ArrayList. However, you still better combine two fields into a single object. You can do it like this:
public class MyObject {
String code;
String nom;
MyObject(String code, String nom) {
this.code = code;
this.nom = nom;
}
}
Now you have a class containing 2 fields. Your aim is to sort a collection of such objects by their second field (nom). You can do this easily since Java 8:
public static void sort1(ArrayList<MyObject> list) {
list.sort((obj1, obj2) -> obj1.nom.compareTo(obj2.nom));
}
Or
public static void sort2(ArrayList<MyObject> list) {
list.sort(Comparator.comparing(MyObject::getNom));
} // However for this you need to add method getNom to MyObject
Remember to put your objects in the collection properly.
For example:
MyObject a = new MyObject("abc", "abide");
MyObject b = new MyObject("cab", "whatever you want");
ArrayList<MyObject> list = new ArrayList<>();
list.add(a);
list.add(b);
trier(list);
I am currently doing a online Java course and am having a bit of trouble with a assignment. The assignment is to essentially create a Hashmap using just Arrays but no other Java Data Structures or methods. This is my code:
public class test {
static String[] array = new String[10];
class Cell<T> {
T first;
Cell<T> next;
Cell(T h, Cell<T> t) {
first = h;
next = t;
}
}
public static int hashFunction(String a) {
int sum = 1;
for (int i = 0; i < a.length(); i++) {
char b = a.charAt(i);
int value = (int) b;
sum *= value;
}
return sum % array.length;
}
public static void arraySetter(String a) {
int position = hashFunction(a);
if (array[position] == null) {
array[position] = a;
} else {
//Need a Linked List here for when there is already a item in the array at the same index.
}
}
public static void printArray() {
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
public static void main(String[] args) {
arraySetter("abc");
printArray();
}
}
My code essentially creates a list of lists. At each position in the Array I now need to create a list which is only initialised when there are two items with the same value for the hashFunction. I haven't written that function yet but my problem now is I don't know how to create a linkedList at each position in the array. Can someone help me out here?
This is the data structure in which you should store your data:
Cell[] array
When using an array such as String[] you will never be able to add any else than instances of String into that array.
When you get a new hashCode, you should create a new one:
array[position] = new Cell<>(a, null);
As it is the first element from the linkedList we will call it the head.
Every time a value with the same hashcode is provided, you will need to iterate from the head until a Cell whose next value is null, then you define it with a new instance of Cell.
This is generally called addLast method, and you ca find a good example here:
https://www.cs.cmu.edu/~adamchik/15-121/lectures/Linked%20Lists/linked%20lists.html
If you want a linked list to avoid collision then you have to declare array which will contain head of the linked list.
Node<K,V>[] table;
Sample code not fully implemented.
class Node<K,V> {
K key;
V value;
Node<K,V> next;
}
Node will contain current key and value .if key is same then you have to override and also next value if you want to use linked list.If you want to use array to avoid collision that time also use node which will contain key and value key is required to check equality and no next variable.
So I have this code:
public class SortedIntList extends IntList
{
private int[] newlist;
public SortedIntList(int size)
{
super(size);
newlist = new int[size];
}
public void add(int value)
{
for(int i = 0; i < list.length; i++)
{
int count = 0,
current = list[i];
if(current < value)
{
newlist[count] = current;
count++;
}
else
{
newlist[count] = value;
count++;
}
}
}
}
Yet, when I run the test, nothing prints out. I have the system.out.print in another class in the same source.
Where am I going wrong?
EDIT: Print code from comment:
public class ListTest
{
public static void main(String[] args)
{
SortedIntList myList = new SortedIntList(10);
myList.add(100);
myList.add(50);
myList.add(200);
myList.add(25);
System.out.println(myList);
}
}
EDIT2: Superclass from comment below
public class IntList
{
protected int[] list;
protected int numElements = 0;
public IntList(int size)
{
list = new int[size];
}
public void add(int value)
{
if (numElements == list.length)
System.out.println("Can't add, list is full");
else {
list[numElements] = value; numElements++;
}
}
public String toString()
{
String returnString = "";
for (int i=0; i<numElements; i++)
returnString += i + ": " + list[i] + "\n";
return returnString;
}
}
Let's walk through the logic of how you want it to work here:
first you make a new sorted list passing 10 to the constructor, which make an integer array of size 10.
now you call your add method passing 100 into it. the method sets position 0 to 100
now you add 50, the method sets 50 in position 0 and 100 in position 1
now you add 200, which gets placed at position 2
and you add 25. which gets set to position 0, and everything else gets shuffled on down
then your method will print out everything in this list.
So here are your problems:
For the first add, you compare current, which is initialized at 0, to 50. 0 will always be less than 50, so 50 never gets set into the array. This is true for all elements.
EDIT: Seeing the super class this is how you should look to fix your code:
public class SortedIntList extends IntList
{
private int[] newlist;
private int listSize;
public SortedIntList(int size)
{
super(size);
// I removed the newList bit becuase the superclass has a list we are using
listSize = 0; // this keeps track of the number of elements in the list
}
public void add(int value)
{
int placeholder;
if (listSize == 0)
{
list[0] = value; // sets first element eqal to the value
listSize++; // incriments the size, since we added a value
return; // breaks out of the method
}
for(int i = 0; i < listSize; i++)
{
if (list[i] > value) // checks if the current place is greater than value
{
placeholder = list[i]; // these three lines swap the value with the value in the array, and then sets up a comparison to continue
list[i] = value;
value = placeholder;
}
}
list[i] = value; // we are done checking the existing array, so the remaining value gets added to the end
listSize++; // we added an element so this needs to increase;
}
public String toString()
{
String returnString = "";
for (int i=0; i<listSize; i++)
returnString += i + ": " + list[i] + "\n";
return returnString;
}
}
Now that I see the superclass, the reason why it never prints anything is clear. numElements is always zero. You never increment it because you never call the superclass version of the add method.
This means that the loop in the toString method is not iterated at all, and toString always just returns empty string.
Note
This is superseded by my later answer. I have left it here, rather than deleting it, in case the information in it is useful to you.
Two problems.
(1) You define list in the superclass, and presumably that's what you print out; but you add elements to newList, which is a different field.
(2) You only add as many elements to your new list as there are in your old list. So you'll always have one element too few. In particular, when you first try to add an element, your list has zero elements both before and after the add.
You should probably have just a single list, not two of them. Also, you should break that for loop into two separate loops - one loop to add the elements before the value that you're inserting, and a second loop to add the elements after it.
we have sequence of 4 characters (A,B,C and D)that map to numbers form 1 to n.
we define components to be:
Component(k) :
A {cell[k]}
if Color(left_k) = Color(k)
then
A <-- A U Component(left_k)
if Color(right_k) = Color(k)
then
A <-- A U Component(left_k)
return A
there is 3 types of operations(the numbers in list indicate the input):
by giving index it should remove the component in that index(the numbers mapping to characters are fixed)
example : AABBBDA is the string. if index is 3 it should return AADA
by giving index it should rotate the string based on the component on that index(the numbers mapping to characters are fixed)
example : AABBBDA is the string. if index is 3 it should return DABBBAA
it should print the string.
inputs are like:
1 2 --> first operation with index=2
2 3 --> second operation with index=3
3 --> third operation
It's an assignment, happy to get help.
this is what i've tried so far:
public static void main(String[] args)
{
int numberOfOps;
String[] print = new String[30];
List list = new List();
Scanner input = new Scanner(System.in);
int count = input.nextInt();
String colors = new String();
colors = input.next();
for(int i = 0; i < count; i++)
{
list.add(colors.charAt(i));
}
numberOfOps = input.nextInt();
list.printElement();
for (int i = 0; i < numberOfOps; i++)
{
int op = input.nextInt();
if(op == 1)
{
int index = input.nextInt();
char c = list.item[index];
int temp = index;
int prevIndex = index;
int nexIndex = index;
if(index != 0)
{
while (list.item[--index] == c)
{
prevIndex--;
}
while (list.item[++temp] == c)
{
nexIndex++;
}
list.setNext(prevIndex-1, nexIndex+1);
}
else
{
while (list.item[++temp] == c)
{
nexIndex++;
}
list.setNext(prevIndex, nexIndex+1);
}
}
if(op == 2)
{
int index = input.nextInt();
}
if(op == 3)
{
print[i] = list.printElement();
}
}
}
here is my List class:
public class List {
// reference to linked list of items
public static final int MAX_LIST = 20;
public static final int NULL = -1;
public char item[] = new char[MAX_LIST]; // data
public int avail;
public int next[] = new int[MAX_LIST]; // pointer to next item
private int numItems; // number of items in list
public List()
{
int index;
for (index = 0; index < MAX_LIST-1; index++)
next[index] = index + 1;
next[MAX_LIST-1] = NULL;
numItems = 0;
avail = 0;
} // end default constructor
public void add(char e)
{
item[avail] = e;
avail = next[avail];
numItems++;
}
public String printElement()
{
String temp = null;
int index = 0;
while(index<avail)
{
temp += item[index];
System.out.println(item[index]);
index = next[index];
}
return temp;
}
public int size()
{
return numItems;
}
public void setNext(int i, int value)
{
next[i] = value;
}
}
if you test it you'll get, it has lots of problems, such as, I have no idea to do the rotate operation, and it has problem with connecting two components when the middle component has been removed.
This is a difficult question to answer, because the requirements are not properly stated.
For example the first bunch of pseudo-code does not make it clear whether A is a set, a multi-set or a list. The notation (use of curly brackets, and U (union?)) seems to say set ... but the output seems to be a list. Or maybe it is supposed to be a schema for a data structure??
And even the inputs are not clearly described.
But putting that on one side, there is still room for some (hopefully) helpful advice.
Make sure that >>you<< understand the requirements. (I imagine that the real requirements for the assignment are better stated than this, and the details have been "lost in translation".)
I would actually use an array list (or a StringBuilder) rather than a linked list for this. (But a properly implemented linked list ... implementing the List API ... would work.)
But whatever data structure you chose, there is no point in implementing it from scratch ... unless you are specifically required to do that. There are perfectly good list classes in the Java standard libraries. You should reuse them ... rather than attempting to reinvent the wheel (and doing a bad job).
If you are required to implement your own data structure type, then your current attempt is a mess. It looks like a hybrid between an array list and a linked list ... and doesn't succeed in being either. (For example, a decent array list implementation does not need a MAX_LIST, and doesn't have next pointers / indexes. And a linked list does not have any arrays inside it.)
I'm trying to create a very, very simple program.
I want my class called Text to simply print out a string, specifically, one letter.
Then in my second class called Window, I want to create an ArrayList of that class, iterate through the list and call the method of my Text class to print out the string. But it does not print anything.
What am I doing wrong?
public class Text {
private String a;
public void printA() {
a = "a";
System.out.print(a);
}
}
and the other class..
import java.util.ArrayList;
public class Window {
private ArrayList<Text> string = new ArrayList<Text>(5);
public Window() {
addText();
}
public void iterate() {
for (int i = 0; i < string.size() - 1; i++) {
string.get(i).printA();
}
}
public void addText() {
for (int i = 0; i <string.size() - 1; i++) {
string.add(new Text());
}
}
public static void main(String[] args) {
Window wind = new Window();
wind.iterate();
}
}
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
initialy the arraylist is empty, so string.size() == 0
the forlus wil not be executed, change to
public void addText(){
string.add(new Text())
}
or even better
public void addText(Text t){
string.add(t)
}
that way you can add Text-object created with different constructors
If you modify iterate to:
public void iterate(){
System.out.println(string.size()-1);
for(int i = 0; i < string.size()-1;i++){
string.get(i).printA();
}
}
You will get -1
Let me explain why:
Each ArrayList instance has a capacity. The capacity is the size of the array used to store the elements in the list. It is always at least as large as the list size. private ArrayList<Text>string = new ArrayList<Text>(5); merely sets the capacity of the underlying array that is the data structure that implement the ArrayList object. size() returns the number of objects inside of the ArrayList not the capcity
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
The for loop's expression doesn't evaluate to true, and therefore you never add a single object to the loop which is why iterate would print -1 if you added the print statement there
The
new ArrayList<Text>(5);
Doesn't mean you have 5 elements array. It means that this is just initial capacity of internal array for storing elements. Due to this your init code:
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
faces no elements in the list with string.size() = 0.
Use this instead (If you like to add 5 elements):
public void addText(){
for(int i = 0; i < 5;i++){
string.add(new Text());
}
}
There is no problem to add more elements (even if the initial capacity was only '5'). From docu "As elements are added to an ArrayList, its capacity grows automatically."
problem it this method.
public void addText(){
for(int i = 0; i <string.size()-1;i++){
string.add(new Text());
}
}
this doesn't add anything at all. because string.size() is 0.
may be you should change it to
public void addText(int size){
for(int i = 0; i <size-1;i++){
string.add(new Text());
}
}
Ps: new Arraylist<Text>(5) actually creates an empty list with initial capacity = 5 (not size). See it here
Well for stater your method in Text needs parameter so it KNOWS to take in 'a' and if you're variable in your parameter is going to be 'a' as well you need use "this." so that the compiler knows that the two are different.
public class Text {
private String a;
public void printA(String a) {
this.a = "a";
System.out.print(a);
}
}
What you are doing wrong is that you are creating the ArrayList with a capacity of 5, but it does not yet have 5 objects in it. Thus, the addText method does nothing. Here's a version that works:
public void addText(){
for(int i = 0; i < 4; i++){
string.add(new Text());
}
}
Note that string.size() - 1 has been changed to 4, becuase string.size() is 0, and you want to add 4 elements to the list. Also, your iterate method could use a little refactoring:
public void iterate(){
for(Text text : string){
string.get(i).printA();
}
}
Instead of a simple loop, an enhanced for is used instead. This is no more than a typing shortcut, but it improves efficiency for LinkedLists.