From: Ivan Pribela Date: Sun, 1 Nov 2015 14:57:03 +0000 (+0100) Subject: Stabla, dodati primeri algoritama nad stablima X-Git-Url: https://svarog.pmf.uns.ac.rs/gitweb/?a=commitdiff_plain;h=16359943f0ee9b1ec9519859c557301240f7d010;p=spa2-materijali.git Stabla, dodati primeri algoritama nad stablima --- diff --git a/Stabla/Primeri za test/StabloIO.java b/Stabla/Primeri za test/StabloIO.java new file mode 100644 index 0000000..59984d3 --- /dev/null +++ b/Stabla/Primeri za test/StabloIO.java @@ -0,0 +1,9 @@ +import org.svetovid.io.SvetovidReader; +import org.svetovid.io.SvetovidWriter; + +public interface StabloIO { + + public Stablo readStablo(SvetovidReader in); + public void printStablo(SvetovidWriter out, Stablo stablo); + +} diff --git a/Stabla/Primeri za test/StabloIOClassic.java b/Stabla/Primeri za test/StabloIOClassic.java new file mode 100644 index 0000000..dcf1d9f --- /dev/null +++ b/Stabla/Primeri za test/StabloIOClassic.java @@ -0,0 +1,85 @@ +import java.util.NoSuchElementException; + +import org.svetovid.io.SvetovidReader; +import org.svetovid.io.SvetovidWriter; + +/** + * Format: + * + * br + * id leviId desniId vrednost (x br) + */ +public class StabloIOClassic implements StabloIO { + + @Override + public Stablo readStablo(SvetovidReader in) { + int br = in.readInt(); + Stablo stablo = null; + for (int i = 0; i < br; i++) { + int id = in.readInt(); + int leviId = in.readInt(); + int desniId = in.readInt(); + String vrednost = in.readLine(); + Stablo levi = leviId == -1 ? null : new Stablo(leviId); + Stablo desni =desniId == -1 ? null : new Stablo(desniId); + Stablo element = new Stablo(id, vrednost, levi, desni); + stablo = insert(stablo, element); + } + return stablo; + } + + private static Stablo insert(Stablo stablo, Stablo element) { + if (stablo == null) { + return element; + } + Stablo found = find(stablo, element.id); + if (found == null) { + throw new NoSuchElementException("id: " + element.id); + } + found.vrednost = element.vrednost; + found.levi = element.levi; + found.desni = element.desni; + return stablo; + } + + private static Stablo find(Stablo stablo, int id) { + if (stablo == null) { + return null; + } + if (stablo.id == id) { + return stablo; + } + Stablo rezultat = find(stablo.levi, id); + if (rezultat != null) { + return rezultat; + } + return find(stablo.desni, id); + } + + @Override + public void printStablo(SvetovidWriter out, Stablo stablo) { + int br = count(stablo); + out.println(br); + iterate(out, stablo); + } + + private static int count(Stablo stablo) { + if (stablo == null) { + return 0; + } + return 1 + count(stablo.levi) + count(stablo.desni); + } + + private static void iterate(SvetovidWriter out, Stablo stablo) { + if (stablo == null) { + return; + } + int id = stablo.id; + int leviId = stablo.levi == null ? -1 : stablo.levi.id; + int desniId = stablo.desni == null ? -1 : stablo.desni.id; + String vrednost = stablo.vrednost; + out.println(id, leviId, desniId, vrednost); + iterate(out, stablo.levi); + iterate(out, stablo.desni); + } +} diff --git a/Stabla/Primeri za test/StabloIOIndent.java b/Stabla/Primeri za test/StabloIOIndent.java new file mode 100644 index 0000000..8e9dc83 --- /dev/null +++ b/Stabla/Primeri za test/StabloIOIndent.java @@ -0,0 +1,73 @@ +import org.svetovid.SvetovidFormatException; +import org.svetovid.io.SvetovidReader; +import org.svetovid.io.SvetovidWriter; + +/** + * Format: + * + * id vrednost + * levi + * desni + */ +public class StabloIOIndent implements StabloIO { + + protected String nullSymbol; + protected String indent; + + public StabloIOIndent() { + this("-", " "); + } + + public StabloIOIndent(String nullSymbol, String indent) { + this.nullSymbol = nullSymbol; + this.indent = indent; + } + + public String getNullSymbol() { + return nullSymbol; + } + + public void setNullSymbol(String nullSymbol) { + this.nullSymbol = nullSymbol; + } + + public String getIndent() { + return indent; + } + + public void setIndent(String indent) { + this.indent = indent; + } + + @Override + public Stablo readStablo(SvetovidReader in) { + try { + int id = in.readInt(); + String vrednost = in.readLine(); + Stablo levi = readStablo(in); + Stablo desni = readStablo(in); + Stablo stablo = new Stablo(id, vrednost, levi, desni); + return stablo; + } catch (SvetovidFormatException e) { + return null; + } + } + + @Override + public void printStablo(SvetovidWriter out, Stablo stablo) { + write(out, stablo, nullSymbol, indent, ""); + } + + protected void write(SvetovidWriter out, Stablo stablo, String nullSymbol, String indent, String prefix) { + if (stablo == null) { + out.println(prefix + nullSymbol); + return; + } + int id = stablo.id; + String vrednost = stablo.vrednost; + out.print(prefix); + out.println(id, vrednost); + write(out, stablo.levi, nullSymbol, indent, prefix + indent); + write(out, stablo.desni, nullSymbol, indent, prefix + indent); + } +} diff --git a/Stabla/Primeri za test/StabloIOPretty.java b/Stabla/Primeri za test/StabloIOPretty.java new file mode 100644 index 0000000..6fcc069 --- /dev/null +++ b/Stabla/Primeri za test/StabloIOPretty.java @@ -0,0 +1,224 @@ +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.svetovid.io.SvetovidReader; +import org.svetovid.io.SvetovidWriter; + +/** + * Format: + * /-- desni + * -(id) vrednost + * \-- levi + */ +public class StabloIOPretty implements StabloIO { + + protected static final String EMPTY_SYMBOL = " "; + protected static final String RIGHT_SYMBOL = "/"; + protected static final String VERTICAL_SYMBOL = "|"; + protected static final String LEFT_SYMBOL = "\\"; + protected static final String HORIZONTAL_SYMBOL = "-"; + + protected String nullSymbol; + protected boolean separated; + protected int length; + + public StabloIOPretty() { + this(null, false, 7); + } + + public StabloIOPretty(String nullSymbol, boolean separated, int length) { + this.nullSymbol = nullSymbol; + this.separated = separated; + this.length = length; + } + + public String getNullSymbol() { + return nullSymbol; + } + + public void setNullSymbol(String nullSymbol) { + this.nullSymbol = nullSymbol; + } + + public boolean isSeparated() { + return separated; + } + + public void setSeparated(boolean separated) { + this.separated = separated; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + if (length < 3) { + throw new IllegalArgumentException("length"); + } + this.length = length; + } + + @Override + public Stablo readStablo(SvetovidReader in) { + return parseStablo(in, nullSymbol, length); + } + + protected Stablo parseStablo(SvetovidReader in, String nullSymbol, int length) { + List elements = new ArrayList<>(); + List levels = new ArrayList<>(); + Pattern levelPattern = Pattern.compile("[\\Q" + LEFT_SYMBOL + HORIZONTAL_SYMBOL + RIGHT_SYMBOL + "\\E]"); + String line = in.readLine(); + while ((line != null) && !line.isEmpty()) { + Matcher matcher = levelPattern.matcher(line); + int level = -1; + if (matcher.find()) { + level = matcher.start(); + } + if (level != -1 && (nullSymbol == null || !line.endsWith(nullSymbol))) { + Stablo stablo = parseStablo(line); + elements.add(stablo); + levels.add(level); + } + line = in.readLine(); + } + Stablo stablo = formStablo(0, elements.size(), levels, elements); + return stablo; + } + + private Stablo parseStablo(String line) { + int id = -1; + String vrednost = null; + int beginIndex = line.indexOf('('); + int endIndex = line.indexOf(')'); + if ((beginIndex != -1) && (endIndex != -1) && (beginIndex < endIndex)) { + vrednost = line.substring(beginIndex + 1, endIndex); + try { + id = Integer.parseInt(vrednost); + } catch (NumberFormatException e) { + throw new NumberFormatException(line); + } + vrednost = line.substring(endIndex + 2); + } else { + throw new NumberFormatException(line); + } + Stablo stablo = new Stablo(id, vrednost); + return stablo; + } + + private Stablo formStablo(int beginIndex, int endIndex, List levels, List elements) { + if (beginIndex >= endIndex) { + return null; + } + int minIndex = beginIndex; + int minLevel = levels.get(minIndex); + for (int i = beginIndex + 1; i < endIndex; i++) { + int level = levels.get(i); + if (level < minLevel) { + minLevel = level; + minIndex = i; + } + } + Stablo stablo = elements.get(minIndex); + Stablo levi = formStablo(minIndex + 1, endIndex, levels, elements); + Stablo desni = formStablo(beginIndex, minIndex, levels, elements); + stablo.levi = levi; + stablo.desni = desni; + return stablo; + } + + @Override + public void printStablo(SvetovidWriter out, Stablo stablo) { + StringBuilder builder = new StringBuilder(); + appendTree(builder, stablo, nullSymbol, separated, length); + out.print(builder.toString()); + } + + protected void appendTree(StringBuilder builder, Stablo stablo, String nullSymbol, boolean separated, int length) { + String[] buildingBlocks = generateBuildingBlocks(length); + appendRight(builder, stablo, nullSymbol, separated, buildingBlocks, true, buildingBlocks[5]); + appendNode(builder, stablo, nullSymbol != null ? nullSymbol : "|", buildingBlocks[4]); + appendLeft(builder, stablo, nullSymbol, separated, buildingBlocks, false, buildingBlocks[5]); + } + + protected void appendNode(StringBuilder builder, Stablo stablo, String nullSymbol, String prefix) { + builder.append(prefix); + if (stablo == null) { + builder.append(nullSymbol); + } else { + builder.append("("); + builder.append(stablo.id); + builder.append(") "); + builder.append(stablo.vrednost); + } + builder.append("\n"); + } + + protected void appendRight(StringBuilder builder, Stablo stablo, String nullSymbol, boolean separated, String[] buildingBlocks, boolean isRight, String prefix) { + if (stablo == null) { + return; + } + if ((nullSymbol != null) || (stablo.desni != null)) { + appendSubtree(builder, stablo.desni, nullSymbol, separated, buildingBlocks, true, prefix); + if (separated) { + appendEmpty(builder, buildingBlocks, prefix); + } + } + } + + protected void appendLeft(StringBuilder builder, Stablo stablo, String nullSymbol, boolean separated, String[] buildingBlocks, boolean isRight, String prefix) { + if (stablo == null) { + return; + } + if ((nullSymbol != null) || (stablo.levi != null)) { + if (separated) { + appendEmpty(builder, buildingBlocks, prefix); + } + appendSubtree(builder, stablo.levi, nullSymbol, separated, buildingBlocks, false, prefix); + } + } + + protected void appendEmpty(StringBuilder builder, String[] buildingBlocks, String prefix) { + builder.append(prefix); + builder.append(buildingBlocks[2]); + builder.append("\n"); + } + + protected void appendSubtree(StringBuilder builder, Stablo stablo, String nullSymbol, boolean separated, String[] buildingBlocks, boolean isRight, String prefix) { + String mojPrefix = prefix; + if (isRight == true) { + mojPrefix = mojPrefix + buildingBlocks[1]; + } + if (isRight == false) { + mojPrefix = mojPrefix + buildingBlocks[3]; + } + String noviPrefix = prefix + (!isRight ? buildingBlocks[2] : buildingBlocks[0]); + appendRight(builder, stablo, nullSymbol, separated, buildingBlocks, isRight, noviPrefix); + appendNode(builder, stablo, nullSymbol, mojPrefix); + noviPrefix = prefix + (isRight ? buildingBlocks[2] : buildingBlocks[0]); + appendLeft(builder, stablo, nullSymbol, separated, buildingBlocks, isRight, noviPrefix); + } + + private String[] generateBuildingBlocks(int length) { + String[] blocks = new String[6]; + blocks[0] = generateBlock(EMPTY_SYMBOL, EMPTY_SYMBOL, EMPTY_SYMBOL, length - 2); + blocks[1] = generateBlock(EMPTY_SYMBOL, RIGHT_SYMBOL, HORIZONTAL_SYMBOL, length - 2); + blocks[2] = generateBlock(EMPTY_SYMBOL, VERTICAL_SYMBOL, EMPTY_SYMBOL, length - 2); + blocks[3] = generateBlock(EMPTY_SYMBOL, LEFT_SYMBOL, HORIZONTAL_SYMBOL, length - 2); + blocks[4] = HORIZONTAL_SYMBOL; + blocks[5] = EMPTY_SYMBOL; + return blocks; + } + + protected String generateBlock(String emptySymbol, String startSymbol, String repeatSymbol, int repeatCount) { + StringBuilder builder = new StringBuilder(); + builder.append(emptySymbol); + builder.append(startSymbol); + for (int i = 0; i < repeatCount; i++) { + builder.append(repeatSymbol); + } + return builder.toString(); + } +} diff --git a/Stabla/Primeri za test/StabloIORandom.java b/Stabla/Primeri za test/StabloIORandom.java new file mode 100644 index 0000000..d3a98ca --- /dev/null +++ b/Stabla/Primeri za test/StabloIORandom.java @@ -0,0 +1,75 @@ +import java.math.BigInteger; +import java.util.Random; +import java.util.concurrent.atomic.AtomicInteger; + +import org.svetovid.io.SvetovidReader; +import org.svetovid.io.SvetovidWriter; + +public class StabloIORandom implements StabloIO { + + protected long seed; + protected int length; + protected int depth; + + public StabloIORandom() { + this(System.currentTimeMillis()); + } + + public StabloIORandom(long seed) { + this(seed, 5, 10); + } + + public StabloIORandom(long seed, int length, int depth) { + this.seed = seed; + this.length = length; + this.depth = depth; + } + + public long getSeed() { + return seed; + } + + public void setSeed(long seed) { + this.seed = seed; + } + + public int getLength() { + return length; + } + + public void setLength(int length) { + this.length = length; + } + + public int getDepth() { + return depth; + } + + public void setDepth(int depth) { + this.depth = depth; + } + + @Override + public Stablo readStablo(SvetovidReader in) { + Random random = new Random(seed); + AtomicInteger sequence = new AtomicInteger(); + Stablo stablo = readStablo(random, sequence, length, depth); + return stablo; + } + + private Stablo readStablo(Random random, AtomicInteger sequence, int length, int depth) { + if (depth <= 0) { + return null; + } + int id = sequence.addAndGet(1 + random.nextInt(9)); + String vrednost = new BigInteger(length, random).toString(36); + Stablo desni = readStablo(random, sequence, length + random.nextInt(5), depth - random.nextInt(5)); + Stablo levi = readStablo(random, sequence, length + random.nextInt(5), depth - random.nextInt(5)); + return new Stablo(id, vrednost, levi, desni); + } + + @Override + public void printStablo(SvetovidWriter out, Stablo stablo) { + throw new UnsupportedOperationException(); + } +} diff --git a/Stabla/Primeri za test/StabloProgram.java b/Stabla/Primeri za test/StabloProgram.java new file mode 100644 index 0000000..148ce7b --- /dev/null +++ b/Stabla/Primeri za test/StabloProgram.java @@ -0,0 +1,123 @@ +import java.util.ArrayList; +import java.util.List; + +class Stablo { + + public final int id; + public String vrednost; + public Stablo levi; + public Stablo desni; + + public Stablo(int id) { + this(id, null); + } + + public Stablo(int id, String vrednost) { + this(id, vrednost, null, null); + } + + public Stablo(int id, String vrednost, Stablo levi, Stablo desni) { + this.id = id; + this.vrednost = vrednost; + this.levi = levi; + this.desni = desni; + } + + @Override + public String toString() { + return "(" + id + " \"" + vrednost + "\"" + (levi == null ? "" : " " + levi) + (desni == null ? "" : " " + desni) + ")"; + } +} + +public class StabloProgram { + + public static void main(String[] args) { + + // Ucitavanje stabla + StabloIO inIO = new StabloIORandom(12345); + Stablo stablo = inIO.readStablo(null); + + // Ispisivanje stabla na ekran + StabloIO outIO = new StabloIOPretty(); + outIO.printStablo(Svetovid.out, stablo); + Svetovid.out.println(); + + // Broj nivoa + int brojNivoa = brojNivoa(stablo); + Svetovid.out.println("Broj nivoa:", brojNivoa); + Svetovid.out.println(); + + // Broj nivoa + int brojElementata = brojElementata(stablo); + Svetovid.out.println("Broj elementata:", brojElementata); + Svetovid.out.println(); + + // Broj nivoa + String najduzaVrednost = najduzaVrednost(stablo); + Svetovid.out.println("Najduza vrednost:", najduzaVrednost); + Svetovid.out.println(); + + // Svi Putevi od korena do listova + sviPutevi(stablo, new ArrayList<>(brojNivoa)); + Svetovid.out.println(); + + // Obrnuto stablo + Stablo obrnuto = obrni(stablo); + outIO.printStablo(Svetovid.out, obrnuto); + Svetovid.out.println(); + + } + + private static int brojElementata(Stablo stablo) { + if (stablo == null) { + return 0; + } + return 1 + brojElementata(stablo.levi) + brojElementata(stablo.desni); + } + + private static int brojNivoa(Stablo stablo) { + if (stablo == null) { + return 0; + } + return 1 + Math.max(brojNivoa(stablo.levi), brojNivoa(stablo.desni)); + } + + private static String najduzaVrednost(Stablo stablo) { + if (stablo == null) { + return null; + } + String rezultat = stablo.vrednost; + String levaVrednost = najduzaVrednost(stablo.levi); + String desnaVrednost = najduzaVrednost(stablo.desni); + if (rezultat == null || (levaVrednost != null && rezultat.length() < levaVrednost.length())) { + rezultat = levaVrednost; + } + if (rezultat == null || (desnaVrednost != null && rezultat.length() < desnaVrednost.length())) { + rezultat = desnaVrednost; + } + return rezultat; + } + + private static void sviPutevi(Stablo stablo, List put) { + if (stablo == null) { + return; + } + put.add(stablo.vrednost); + if ((stablo.levi == null) && (stablo.desni == null)) { + Svetovid.out.println("Put: " + put); + } + sviPutevi(stablo.levi, put); + sviPutevi(stablo.desni, put); + put.remove(put.size() - 1); + } + + private static Stablo obrni(Stablo stablo) { + if (stablo == null) { + return null; + } + Stablo levi = obrni(stablo.levi); + Stablo desni = obrni(stablo.desni); + Stablo obrnuto = new Stablo(stablo.id, stablo.vrednost, desni, levi); + return obrnuto; + } +} diff --git a/Stabla/Primeri za test/classic.txt b/Stabla/Primeri za test/classic.txt new file mode 100644 index 0000000..8afb799 --- /dev/null +++ b/Stabla/Primeri za test/classic.txt @@ -0,0 +1,50 @@ +49 +5 94 10 h +94 136 97 a +136 214 143 54 +214 219 -1 3g +219 226 -1 ph +226 -1 229 y4 +229 -1 230 515 +230 237 -1 mo0 +237 251 245 1adr +251 -1 -1 a5f1 +245 -1 -1 2jl1 +143 -1 147 ak +147 161 152 4a0 +161 182 165 14 +182 189 -1 50f5 +189 192 -1 2uh8 +192 193 -1 27r6 +193 194 -1 1ol4m +194 209 201 2a3aq +209 -1 -1 7aa8b +201 -1 -1 2l3k6 +165 171 167 4ac3 +171 173 -1 1g7an +173 -1 -1 8deri +167 -1 -1 fe2n +152 -1 -1 2p7 +97 106 -1 1m +106 134 109 81 +134 -1 -1 1pu +109 117 -1 1by +117 129 123 iu0 +129 -1 -1 8tl8 +123 -1 -1 3bds +10 67 18 9 +67 72 71 e6 +72 85 76 6n +85 87 -1 km1 +87 -1 -1 2u0n +76 -1 -1 1nm +71 -1 -1 36 +18 29 26 1m +29 58 32 67 +58 -1 -1 32 +32 51 41 mg +51 -1 52 14y +52 -1 -1 7uq +41 44 -1 h1 +44 -1 -1 1ec +26 -1 -1 19 diff --git a/Stabla/Primeri za test/indent.txt b/Stabla/Primeri za test/indent.txt new file mode 100644 index 0000000..caecf7a --- /dev/null +++ b/Stabla/Primeri za test/indent.txt @@ -0,0 +1,99 @@ +5 h + 94 a + 136 54 + 214 3g + 219 ph + 226 y4 + - + 229 515 + - + 230 mo0 + 237 1adr + 251 a5f1 + - + - + 245 2jl1 + - + - + - + - + - + 143 ak + - + 147 4a0 + 161 14 + 182 50f5 + 189 2uh8 + 192 27r6 + 193 1ol4m + 194 2a3aq + 209 7aa8b + - + - + 201 2l3k6 + - + - + - + - + - + - + 165 4ac3 + 171 1g7an + 173 8deri + - + - + - + 167 fe2n + - + - + 152 2p7 + - + - + 97 1m + 106 81 + 134 1pu + - + - + 109 1by + 117 iu0 + 129 8tl8 + - + - + 123 3bds + - + - + - + - + 10 9 + 67 e6 + 72 6n + 85 km1 + 87 2u0n + - + - + - + 76 1nm + - + - + 71 36 + - + - + 18 1m + 29 67 + 58 32 + - + - + 32 mg + 51 14y + - + 52 7uq + - + - + 41 h1 + 44 1ec + - + - + - + 26 19 + - + - diff --git a/Stabla/Primeri za test/pretty.txt b/Stabla/Primeri za test/pretty.txt new file mode 100644 index 0000000..5f1b623 --- /dev/null +++ b/Stabla/Primeri za test/pretty.txt @@ -0,0 +1,49 @@ + /-----(26) 19 + /-----(18) 1m + | | /-----(41) h1 + | | | \-----(44) 1ec + | | /-----(32) mg + | | | | /-----(52) 7uq + | | | \-----(51) 14y + | \-----(29) 67 + | \-----(58) 32 + /-----(10) 9 + | | /-----(71) 36 + | \-----(67) e6 + | | /-----(76) 1nm + | \-----(72) 6n + | \-----(85) km1 + | \-----(87) 2u0n +-(5) h + | /-----(97) 1m + | | | /-----(109) 1by + | | | | | /-----(123) 3bds + | | | | \-----(117) iu0 + | | | | \-----(129) 8tl8 + | | \-----(106) 81 + | | \-----(134) 1pu + \-----(94) a + | /-----(152) 2p7 + | /-----(147) 4a0 + | | | /-----(167) fe2n + | | | /-----(165) 4ac3 + | | | | \-----(171) 1g7an + | | | | \-----(173) 8deri + | | \-----(161) 14 + | | \-----(182) 50f5 + | | \-----(189) 2uh8 + | | \-----(192) 27r6 + | | \-----(193) 1ol4m + | | | /-----(201) 2l3k6 + | | \-----(194) 2a3aq + | | \-----(209) 7aa8b + | /-----(143) ak + \-----(136) 54 + \-----(214) 3g + \-----(219) ph + | /-----(230) mo0 + | | | /-----(245) 2jl1 + | | \-----(237) 1adr + | | \-----(251) a5f1 + | /-----(229) 515 + \-----(226) y4