Reputation: 85
I am working on my A-Level computing project, and I have a 2D array, with in the x direction name, password, state (just a variable). I want to sort the 2D array using a bubble sort so that I can implement a binary search on the data. Here is the code I have come up with:
public String[][] sort(String[][] details, int len){
boolean flag = false;
String[] temp = new String[3];
int z=0;
do{
flag = false;
for (int i = 0; i < len; i++){
if(details[0][i].charAt(0) > details[0][i + 1].charAt(0)){
flag = true;
temp[0] = details[0][i];
temp[1] = details[1][i];
temp[2] = details[2][i];
details[0][i] = details[0][i + 1];
details[1][i] = details[1][i + 1];
details[2][i] = details[2][i + 1];
details[0][i + 1] = temp[0];
details[1][i + 1] = temp[1];
details[2][i + 1] = temp[2];
}
}
len--;
} while (flag);
return details;
}
However it has sort of come to my attention I could do this much easier using object orientation which is something I would love to try and have a go at. Does anyone know where I could start learning about object orientation in this sort of context, the guides I have searched for online, just talk about shapes etc... and I am really not sure how to implement those guides into this situation.
From my understanding, what I could do is set up an object with three variables, name, password and state; and when I called upon a name, I could also get the details for the password and state. Am I along the right lines here? and if so can anyone show me how I can do this please.
Thanks a lot.
Sam
edit - Thanks for all the help guys, thanks to this, I have worked out how to implement this in my project, and it is amazing how much easier it makes the code! Thanks a lot! For anyone else struggling with this problem, this is my final code:
public class loginDetailsOO {
public static void main (String[] args){
loginDetailsOO object = new loginDetailsOO();
object.run();
}
public void run(){
String password = encrypt("password");
String location = "textFiles\\PasswordScreen.txt";
int lines = numberOfLines(location);
User[] user = fileToArray(location, lines);
int index = searchForUsername(user, lines / 4, "VELINGUARD");
if (password.equals(user[index].getPassword())){
System.out.println("entrance is granted");
}
User u = new User("ball", "pass", 0);
addToFile(u, "VELINGUARD");
}
public void addToFile(User newUser, String currentUsername){
String location = "textFiles\\PasswordScreen.txt";
newUser.setUsername(newUser.getUsername().toUpperCase());
int lines = numberOfLines(location);
User[] user = fileToArray(location, lines);
int line = lines / 4;
int index = searchForUsername(user, line, currentUsername);
if (user[index].getState() == 1){
if (searchForUsername(user,line, newUser.getUsername()) == -1) {
newUser.setPassword(encrypt(newUser.getPassword()));
user[line] = newUser;
user = sort(user, line);
writeToFile(location, user, line);
} else {
System.out.println("User already exists");
}
} else {
System.out.println("Permission not granted");
}
}
public User[] sort(User[] user, int len){
boolean flag = false;
User temp;
int z=0;
do{
flag = false;
for (int i = 0; i < len; i++){
if(user[i].getUsername().compareTo(user[i + 1].getUsername()) > 0){
flag = true;
temp = user[i];
user[i] = user[i + 1];
user[i + 1] = temp;
}
}
len--;
} while (flag);
return user;
}
public String encrypt (String password){
String encrypted = "";
char temp;
int ASCII;
for (int i = 0; i < password.length(); i++){
temp = password.charAt(i);
ASCII = (int) temp;
if (ASCII >= 32 && ASCII <= 127)
{
int x = ASCII - 32;
x = (x + 6) % 96;
if (x < 0)
x += 96; //java modulo can lead to negative values!
encrypted += (char) (x + 32);
}
}
return encrypted;
}
public String decrypt (String password){
String decrypted = "";
char temp;
int ASCII;
for (int i = 0; i < password.length(); i++){
temp = password.charAt(i);
ASCII =(int) temp;
if (ASCII >= 32 && ASCII <= 127)
{
int x = ASCII - 32;
x = (x - 6) % 96;
if (x < 0)
x += 96;
decrypted += (char) (x + 32);
}
}
return decrypted;
}
public User[] fileToArray(String file, int lines) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(file)));
int line = lines / 4;
String temp[] = new String[3];
User[] user = new User[line];
for (int i = 0; i < line; i++){
temp[0] = reader.readLine();
temp[1] = reader.readLine();
temp[2] = reader.readLine();
reader.readLine();
user[i] = new User(temp[0], temp[1], Integer.parseInt(temp[2]));
}
return user;
} catch(Exception e){
System.out.println("File not found");
return null;
}
}
public void writeToFile(String location, User[] user, int length){
try {
File f = new File(getClass().getResource(location).toURI());
f.setWritable(true);
FileWriter w = new FileWriter(f);
BufferedWriter writer = new BufferedWriter(w);
wipeFile(f);
for (int i = 0; i <= length; i++){
writer.write(user[i].getUsername());
writer.newLine();
writer.write(user[i].getPassword());
writer.newLine();
writer.write(user[i].getState());
writer.newLine();
writer.write("-");
writer.newLine();
}
writer.close();
f.setReadOnly();
} catch(Exception e){System.out.println("error writing to file");}
}
public void wipeFile(File f) {
try {
PrintWriter wiper = new PrintWriter(f);
wiper.println("");
} catch (Exception ex) {
System.out.println("error wiping file");
}
}
public int searchForUsername(User[] user, int lines, String name){ //implements binary search
int low = 0;
int high = lines - 1;
int mid;
while (low <= high){ //by using a while loop it means if it is an empty file than there will be no issue
mid = low + high;
mid = mid / 2;
if ((int) name.charAt(0) > (int) user[mid].getUsername().charAt(0)){
low = mid + 1;
} else if ((int) name.charAt(0) < (int) user[mid].getUsername().charAt(0)) {
high = mid - 1;
} else {
if (user[mid].getUsername().equals(name)){
return mid;
}
else {
int pass = 0;
do{
if (user[mid - pass].getUsername().equals(name)){
return mid - pass;
} else if (user[mid + pass].getUsername().equals(name)) {
return mid + pass;
}
} while (true);
}
}
}
System.out.println("Name not found");
return -1;
}
public int numberOfLines(String file) {
try{
LineNumberReader lnr = new LineNumberReader(new InputStreamReader(getClass().getResourceAsStream(file)));
lnr.skip(Long.MAX_VALUE);
int length = (lnr.getLineNumber() + 1); //Add 1 because line index starts at 0
lnr.close();
return length;
}catch(Exception e){
System.out.println("File not Found");
return 0;
}
}
and:
public class User{
private String username;
private String password;
private int state;
public User(){
username = "";
password = "";
state = 0;
}
public User(String user, String pass, int st){
username = user;
password = pass;
state = st;
}
public void setUsername(String name){
username = name;
}
public void setPassword(String pass){
password = pass;
}
public void setState(int st){
state = st;
}
public String getUsername(){
return username;
}
public String getPassword(){
return password;
}
public int getState(){
return state;
}
Upvotes: 2
Views: 89
Reputation: 6780
Make a Detail
class that stores the details you are currently storing in an array. Something like:
public class Detail {
public String name;
public String password;
public String state;
}
Then modify your existing code to work with Detail
objects instead of arrays of arrays.
public Detail[] sort(Detail[] details){
boolean flag = false;
do{
flag = false;
for (int i = 0; i < details.length; i++){
if(details[i].name.compareTo(details[i + 1].name) > 0){
flag = true;
Detail temp = details[i];
details[i] = details[i + 1];
details[i + 1] = temp;
}
}
len--;
} while (flag);
return details;
}
Note that it would be even better to just use a library function to sort the array, but if you want to do it this way to learn about bubble sort, that's fine.
You will probably need to modify the other parts of your code to use Detail
objects as well.
Upvotes: 1
Reputation: 70909
Bubble sort is meant to be used in only one context in Computer Science, as an example of how simple approaches can sometimes be the worst approach. If you don't remember anything else about sorting, remember that you should never use bubble sort (quicksort is almost always a safer bet).
In order to do this with object orientation, you need objects. These are the code equivalent of which "nouns" are going to be describing the problem. This might mean you would need (minimally) a:
The problem is that the ordering of something is an action (a verb) and not typically a noun. However, we can make it a noun (thank you English for having "gerunds"). This adds:
The main problems come into play when one realizes that without information hiding you don't have much in the way of Object-Orientation. To do this many of the items would require their data being private, and it is something of a try a few times to find the right balance between the "data structure" approach of all exposed data and the OO approach of all private data.
A very pure OO-approach might look like:
class Book extends Entry {
public String getTitle() {
...
}
}
List<Book> books = new List<Book>();
books.add(new Book(...));
books.add(new Book(...));
books.add(new Book(...));
Sorter sorter = new QuickSorter();
Comparison<Book> byTitle = new Comparison<Book>() {
public int compare(Book one, Book two) {
return String.compare(one.getTitle(), two.getTitle());
}
}
sorter.sort(books, byTitle);
Of course, there are different things that people value, and so they might come up with valid, but entirely different OO structures.
Finally, there is already a very good OO-ish set of data structure in java.util
, and while it may be fun to create a new one, one should use the java.util.List
and friends because they already implement the fastest sorting algorithms (in Collections.sort
) and most other libraries expect a java.util.List
and not a my.custom.List
.
Have fun, and happy hacking!
Upvotes: 1