How can I delete a node from a BST?
I need an algorithm to do that in Dr. Scheme.
You basically toss the BST you have now, and create a new one sans the element.
You can do this by recursively descending the tree. If your item is less than the root datum, create a BST whose root and greater-than branch is copied from what you have now, but whose less-than branch is the result from a recursive call.
It's very similar to how you add a node, but when you get to the one you were searching for, merge the two BSTs below it and return the result. There are surely existing questions about how to do that already.
Assuming your binary search tree uses straight forward cons cells with content only at the leaves, and assuming you are working on a homework assignment:
You can use set-car! or set-cdr! to change the content of a cons cell.
Related
In org-mode, if I have an ordered list such as
first item
second item
third item
fourth item
and I demote an item, the demoted item is automatically renumbered restarting from 1:
first item
second item
third item
fourth item
Is there a way to make org-mode (or emacs in general) to automatically renumber demoted items like when using legal numbering?
I mean this:
first item
second item
2.1. third item
2.1.1. fourth item
Org-mode doesn't currently provide this functionality, and nor, to my knowledge, does any existing minor mode. The only emacs package I'm aware of which does is hyperbole, whose koutline module (here is an example-document, exported to html) provides an impressive suite of outline-editing tools, and supports hierarchical legal numbering.
(koutline also supports "klinks" between numbered paragraphs which refer to an invariant ID assigned to each paragraph on creation, so that the links remain valid even if one moves a paragraph from its original position in the document hierarchy.)
Unfortunately koutline is incompatible with org-mode. It does have a rudimentary HTML-export, but this is unlikely, in its present form, to satisfy anyone used to the wide range of export options provided by org-export. Nevertheless, depending on your use-case, koutline might be an adequate tool.
Org-mode's built-in list styles include
unordered lists, using -, + or *,
ordered lists, using 1. or 1), and
definition lists, using :: to separate terms from definitions.
You can cycle a given list between these styles using S-left and S-right.
There are a number of forum posts and mailing list entries asking for legal numbering, but unfortunately I don't think it's supported.
I can create a multi-level lists with:
1. Step 1
1. Substep 1
1. Substep 2
1. Step 2
1. Step 3
When rendered in Gitea, it will use different number systems for the two levels, e.g. "1,2,3" or "i,ii,iii".
I'm trying to implement a Towers of Hanoi recursively with Common Lisp. I know what the recursive calls are and how they work, but I'm just lost with how I would go about moving something from the end of one list, to the end of another list. I was trying to do some research on how to do this, but I couldn't find anything online.
Any help would be greatly appreciated.
Thanks!
You can remove the last element of a list with butlast, get last element with last, and you cat append a list to another list with append (you just cons your element to be added so that it's a one element list). Working on the end of lists in CL are not optimal as every function needs to traverse the list in order to find the last one, but it is done when you need to add/remove in both ends.
With Tower of Hanoi you are stacking disks on top of each other and the last one put is the first one out. In Common Lisp (in fact any Lisp cousin) you can easily add to front and remove from front with doing (cdr pole-a) in the recursive call to remove the top element from pole-a and add to pole-b with (cons (car pole-a) pole-b) in the recursive call.
I imagine you need this to actually be able to see which disk is moved in each stage, since you need no such structure to calculate the moves needed. In such a scenario you only need the names of the poles and the level the recursion and the number of disks you want to move in this round.
I'm optimizing my code at the moment (android game), and wanted to replace all foreach(for(:)) with normal fors. Is there a way to find them all? Ctrl-F only looks through the current file and Ctrl-H doesn't seem to find any java constructs (not sure if right word: ifs, whiles, accessors etc.). Preferably without a plugin, but any answer accepted. It would also be nice if there would be a possibility to search for any string (* in Search).
TL;DR: Looking for way to find all foreaches in eclipse.
First of all, I must say, this sounds like a really strange optimization. Keep in mind that if you have, say, a LinkedList you would be far worse of going through a
for (int i = 0; i < list.size(); i++) {
element = list.get(i);
...
loop, than using an iterator (which for-each loops does). Smells micro-optimizations long way to me.
That said, here's a solution for you:
Make sure the root source folder is selected
Click Search / File Search
Mark Scope as "Selected resources"
Mark Regular expression
Search for a regular expression such as for\s*\(.*:
The expression matches strings on the form for, followed by some white whitespace, followed by ( followed by some characters, followed by : (which kind of characterizes a Java for-each loop).
Right-Click on the project, choose search and you're able to replace all for-commands with a regular expression like for(.*;.*;.*) with other expressions you want to.
Ok I need some help with thinking through this conceputally.
I need to check if a list and another list is structurally equal.
For example:
(a (bc) de)) is the same as (f (gh) ij)), because they have the same structure.
Now cleary the base case will be if both list are empty they are structurally equal.
The recursive case on the other hand I'm not sure where to start.
Some ideas:
Well we are not going to care if the elements are == to each other because that doesn't matter. We just care in the structure. I do know we will car down the list and recursively call the function with the cdr of the list.
The part that confuses me is how do you determine wheter an atom or sublist has the same structure?
Any help will be appreciated.
You're getting there. In the (free, online, excellent) textbook, this falls into section 17.3, "Processing two lists simultaneously: Case 3". I suggest you take a look.
http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-1.html#node_toc_node_sec_17.3
One caveat: it looks like the data definition you're working with is "s-expression", which you can state like this:
;; an s-expression is either
;; - the empty list, or
;; - (cons symbol s-expression), or
;; - (cons s-expression s-expression)
Since this data definition has three cases, there are nine possibilities when considering two of them.
John Clements
(Yes, you could reduce the number of cases by embedding the data in the more general one that includes improper lists. Doesn't sound like a good idea to me.)
My goal is coming up with a script to track the point a line was added, even if the line is subsequently modified or moved around (both of which confuse traditional vcs 'blame' scripts. I've done some minor background research (see bottom) but didn't find anything useful. I have a concept for how to proceed but the runtime would be atrocious (there's a factorial involved).
The two missing features are tracking edited-in-place lines separate from a deletion-and-addition of that line, and tracking entire functions moved around so they're in different hunks. For those experienced with diff but unfamiliar with the terminology, a subsequence is a contiguous group of + or - lines, with a type of either delete (all -), add (all +), or replace (a combination). I need more information, on moves and edit-in-place lines, vaguely alluded to in an entry on c2: DiffAlgorithm (paragraph starts with "My favorite mode"). Does anyone know what that is? (seems to be based on Tichy, see bottom.)
Here's more info on the two missing features:
no concept of a change on a line, (a fourth type, something like edit-in-place). In this hunk, the parent of 'bc' is 'b' but 'd' is new and isn't a descendant of 'b':
a
-b
+bc
+d
The workaround for this isn't too complicated, if the position of edits is the same (just an expanded version of markup_instraline_changes but comparing edit distance on all equal-sized subsets of old and new lines.
no concept of "moving" code that preserves the ownership of the lines, e.g. this diff shouldn't alter the ownership of "line", although its position changes.
a
-line
c
+line
This could be dealt with in the same way but with much worse runtime (instead of only checking single blocks marked 'replace', you'd need to check Levenshtein distance between all added against all removed lines) and with likely false positives (some, like whitespace-only lines, aren't relevant to my problem).
Research I've done: reading about gestalt pattern matching (Ratcliff and Obershelp, used in Python's difflib) and An O(ND) Difference Algorithm and its Variations (EW Myers).
After posting the question, I found references to Tichy84 which appears to be The string-to-string correction problem with block moves (which I haven't read yet) according to Walter Tichy's paper a year later on RCS
You appear to be interested in origin tracking, the problem of tracing where a line came from.
Ideally, you'd instrument the editor to remember how things were edited, and store the edits with the text in your repository, thus solving the problem trivially, but none of us software engineers seem to be smart enough to implement this simple idea.
As a weak substitute, one can look at a sequence of source code revisions from the repository and reconstruct a "plausible" history of changes. This is what you seem to be doing by proposing the use of "diff". As you've noted, diff doesn't understand the idea of "moving" or "copying".
SD Smart Differencer tools compare source text by parsing the text according to the langauge it is in, discovering the code structures, and computing least-Levensthein differences in terms of programming language constructs (identifiers, expressions, statements, blocks, classes, ...) and abstract editing operators "insert", "delete", "copy", "move" and "rename identifier within a scope". They produce diff-like output, a little richer because they tell you line/column -> line/column with different editing operations.
Obviously the "move" and "copy" edits are the ones most interesting to you in terms of tracking specific lines (well, specific language constructs). Our experience is that code goes through lots of copy and edits, too, which I suspect won't surprise you.
These tools are in Beta, and are presently available for COBOL, Java and C#. Lots of other langauges are in the pipe, because the SmartDifferencer is built on top of a langauge-parameterized infrastructure, DMS Software Reengineering Toolkit, which has quite a number of already existing, robust langauge grammars.
I think the idea of what amount of editing a line that can be done while it remains a descendent of some previously written line is very subjective, and based on context, both things that a computer cannot work with. You'd have to specify some sort of configurable minimum similarity on lines in your program I think... The other problem is that it is entirely possible for two identical lines to be written completely independently (for example incrementing the value of some variable), and this will be be quite a common thing, so your desired algorithm won't really give truthful or useful information about a line quite often.
I would like to suggest an algorithm for this though (which makes tons of hopefully obvious assumptions by the way) so here goes:
Convert both texts to lists of lines
Copy the lists and Strip all whitespace from inside of each line
Delete blank lines from both lists
Repeat
Do a Levenshtein distance from the old to new lists ...
... keeping all intermediate data
Find all lines in the new text that were matched with old lines
Mark the line in both new/old original lists as having been matched
Delete the line from the new text (the copy)
Optional: If some matched lines are in a contiguous sequence ...
... in either original text assign them to a grouping as well!
Until there is nothing left but unmatchable lines in the new text
Group together sequences of unmatched lines in both old and new texts ...
... which are contiguous in the original text
Attribute each with the line match before and after
Run through all groups in old text
If any match before and after attributes with new text groups for each
//If they are inside the same area basically
Concatenate all the lines in both groups (separately and in order)
Include a character to represent where the line breaks are
Repeat
Do a Levenshtein distance on these concatenations
If there are any significantly similar subsequences found
//I can't really define this but basically a high proportion
//of matches throughout all lines involved on both sides
For each matched subsequence
Find suitable newline spots to delimit the subsequence
Mark these lines matched in the original text
//Warning splitting+merging of lines possible
//No 1-to-1 correspondence of lines here!
Delete the subsequence from the new text group concat
Delete also from the new text working list of lines
Until there are no significantly similar subsequences found
Optional: Regroup based on remaining unmatched lines and repeat last step
//Not sure if there's any point in trying that at the moment
Concatenate the ENTIRE list of whitespaced-removed lines in the old text
Concatenate the lines in new text also (should only be unmatched ones left)
//Newline character added in both cases
Repeat
Do Levenshtein distance on these concatenations
Match similar subsequences in the same way as earlier on
//Don't need to worry deleting from list of new lines any more though
//Similarity criteria should be a fair bit stricter here to avoid
// spurious matchings. Already matched lines in old text might have
// even higher strictness, since all of copy/edit/move would be rare
While you still have matchings
//Anything left unmatched in the old text is deleted stuff
//Anything left unmatched in the new text is newly written by the author
Print out some output to show all the comparing results!
Well, hopefully you can see the basics of what I mean with that completely untested algorithm. Find obvious matches first, and verbatim moves of chunks of decreasing size, then compare stuff that's likely to be similar, then look for anything else which is similar, but both modified and moved: probably just coincidentally similar.
Well, if you try implementing this, tell me how it works out, and what details you changed, and what kind of assignments you made to the various variables involved... I expect there will be some test cases where it works brilliantly and others where it just abyssmally fails due to some massive oversight. The idea is that most stuff will be matched before you get to the inefficient final loop, and indeed the previous one