Balancing of a binary search tree. Not working? - c++17

AddressSanitizer:DEADLYSIGNAL
==30==ERROR: AddressSanitizer: stack-overflow on address 0x7ffca44eafe8 (pc 0x00000034586e bp 0x7ffca44eb010 sp 0x7ffca44eaff0 T0)
==30==ABORTING
// counting nodes as height of tree
int height(TreeNode* root)
{
if(root == NULL)
{
return 0;
}
return max(height(root->left),height(root->right)) + 1;
}
TreeNode* LLRotation(TreeNode* p)
{
TreeNode* q = p->left;
q->right = p;
return q;
}
TreeNode* LRRotation(TreeNode* p)
{
TreeNode* q = p->left;
TreeNode* r = q->right;
r->right = p;
r->left = q;
return r;
}
TreeNode* RRRotation(TreeNode* p)
{
TreeNode* q = p->right;
q->left = p;
return q;
}
TreeNode* RLRotation(TreeNode* p)
{
TreeNode* q = p->right;
TreeNode* r = q->left;
r->left = p;
r->right = q;
return r;
}
TreeNode* balanceBST(TreeNode* root) {
if(root == NULL)
{
return NULL;
}
root->left = balanceBST(root->left);
root->right = balanceBST(root->right);
if(root->left != NULL || root->right != NULL)
{
if(abs(height(root->left) - height(root->right)) > 1)
{
if(height(root->left) - height(root->right) == 2)
{
if(height(root->left->left) - height(root->left->right) == 1)
{
return LLRotation(root);
}
else {
return LRRotation(root);
}
}
if(height(root->left) - height(root->right) == -2)
{
if(height(root->right->left) - height(root->right->right) == -1)
{
return RRRotation(root);
}
else {
return RLRotation(root);
}
}
}
}
return root;
I was trying to balance a binary search tree but this code is not working i don't know why.
when i was degugging it shows segmentation fault in vs code and the below error message in leetcode.
AddressSanitizer:DEADLYSIGNAL
==30==ERROR: AddressSanitizer: stack-overflow on address 0x7ffca44eafe8 (pc 0x00000034586e bp 0x7ffca44eb010 sp 0x7ffca44eaff0 T0)
==30==ABORTING
Idea for balancing:-
--start from bottom and then going to top
--check the balance factor of each node if it is not balanced then apply appropriate rotations
as we do in avl tree.
can anyone find the error in this code?

Related

Loop recurring formula

I want to add a recurring formula to my script for a timesheet wherein when I punch out it will calculate the duration of Time In and Time out, then it would lock the values of time in and out and the total duration. Thank you in advance if you would help me out.
function setValue(cellName, value) {
SpreadsheetApp.getActiveSpreadsheet().getRange(cellName).setValue(value);
}
function getValue(cellName) {
return SpreadsheetApp.getActiveSpreadsheet().getRange(cellName).getValue();
}
function getNextRow() {
return SpreadsheetApp.getActiveSpreadsheet().getLastRow() + 1;
}
function getNextRow2() {
return SpreadsheetApp.getActiveSpreadsheet().getLastRow() + 2;
}
function setUser1(x) {
setValue('I1', 'User 1');
}
function setUser2() {
setValue('I1', 'User 2');
}
function addRecord(a, b, c) {
var row = getNextRow();
setValue('A' + row, a);
setValue('B' + row, b);
setValue('C' + row, c);
}
function isUserIn(user) {
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
for (var i = lastRow; i >= 1; i--) {
if (getValue("A" + i) == user) {
if (getValue("C" + i) > getValue("B" + i)) {
return false;
}
return true;
}
}
}
function punchIN() {
var user = getValue("I1");
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
addRecord(getValue('I1'), new Date());
}
function punchOut() {
var user = getValue("I1");
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
if (isUserIn(user)) {
for (var i = lastRow; i >= 1; i--) {
if (getValue("A" + i) == user) {
if (getValue("C" + i) == "") {
setValue("C" + i, new Date(), "IN");
}
}
}
}
}
it should basically look like this
enter image description here
Please help me do this thanks. I actually have no background in coding it would be a big help if someone could help me with this.
Modify your punchout() function as follow:
function punchOut() {
var user = getValue("I1");
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
if (isUserIn(user)) {
for (var i = lastRow; i >= 1; i--) {
if (getValue("A" + i) == user) {
if (getValue("C" + i) == "") {
setValue("C" + i, new Date());
var duration = (getValue("C" + i) - getValue("B" + i)) / (60 * 60 * 1000);
setValue("D" + i, duration);
SpreadsheetApp.getActiveSheet().getRange("B" + i + ":C" + i).setLocked(true);
break;
}
}
}
}
}
Also you can modify your getNextRow is follow:
function getNextNRow(n) {
return SpreadsheetApp.getActiveSpreadsheet().getLastRow() + n;
}

to read the images in order in opencv C++ using glob [duplicate]

I'm sorting strings that are comprised of text and numbers.
I want the sort to sort the number parts as numbers, not alphanumeric.
For example I want: abc1def, ..., abc9def, abc10def
instead of: abc10def, abc1def, ..., abc9def
Does anyone know an algorithm for this (in particular in c++)
Thanks
I asked this exact question (although in Java) and got pointed to http://www.davekoelle.com/alphanum.html which has an algorithm and implementations of it in many languages.
Update 14 years later: Dave Koelle’s blog has gone off line and I can’t find his actual algorithm, but here’s an implementation.
https://github.com/cblanc/koelle-sort
Several natural sort implementations for C++ are available. A brief review:
natural_sort<> - based on Boost.Regex.
In my tests, it's roughly 20 times slower than other options.
Dirk Jagdmann's alnum.hpp, based on Dave Koelle's alphanum algorithm
Potential integer overlow issues for values over MAXINT
Martin Pool's natsort - written in C, but trivially usable from C++.
The only C/C++ implementation I've seen to offer a case insensitive version, which would seem to be a high priority for a "natural" sort.
Like the other implementations, it doesn't actually parse decimal points, but it does special case leading zeroes (anything with a leading 0 is assumed to be a fraction), which is a little weird but potentially useful.
PHP uses this algorithm.
This is known as natural sorting. There's an algorithm here that looks promising.
Be careful of problems with non-ASCII characters (see Jeff's blog entry on the subject).
Partially reposting my another answer:
bool compareNat(const std::string& a, const std::string& b){
if (a.empty())
return true;
if (b.empty())
return false;
if (std::isdigit(a[0]) && !std::isdigit(b[0]))
return true;
if (!std::isdigit(a[0]) && std::isdigit(b[0]))
return false;
if (!std::isdigit(a[0]) && !std::isdigit(b[0]))
{
if (a[0] == b[0])
return compareNat(a.substr(1), b.substr(1));
return (toUpper(a) < toUpper(b));
//toUpper() is a function to convert a std::string to uppercase.
}
// Both strings begin with digit --> parse both numbers
std::istringstream issa(a);
std::istringstream issb(b);
int ia, ib;
issa >> ia;
issb >> ib;
if (ia != ib)
return ia < ib;
// Numbers are the same --> remove numbers and recurse
std::string anew, bnew;
std::getline(issa, anew);
std::getline(issb, bnew);
return (compareNat(anew, bnew));
}
toUpper() function:
std::string toUpper(std::string s){
for(int i=0;i<(int)s.length();i++){s[i]=toupper(s[i]);}
return s;
}
Usage:
std::vector<std::string> str;
str.push_back("abc1def");
str.push_back("abc10def");
...
std::sort(str.begin(), str.end(), compareNat);
To solve what is essentially a parsing problem a state machine (aka finite state automaton) is the way to go. Dissatisfied with the above solutions i wrote a simple one-pass early bail-out algorithm that beats C/C++ variants suggested above in terms of performance, does not suffer from numerical datatype overflow errors, and is easy to modify to add case insensitivity if required.
sources can be found here
For those that arrive here and are already using Qt in their project, you can use the QCollator class. See this question for details.
Avalanchesort is a recursive variation of naturall sort, whiche merge runs, while exploring the stack of sorting-datas. The algorithim will sort stable, even if you add datas to your sorting-heap, while the algorithm is running/sorting.
The search-principle is simple. Only merge runs with the same rank.
After finding the first two naturell runs (rank 0), avalanchesort merge them to a run with rank 1. Then it call avalanchesort, to generate a second run with rank 1 and merge the two runs to a run with rank 2. Then it call the avalancheSort to generate a run with rank 2 on the unsorted datas....
My Implementation porthd/avalanchesort divide the sorting from the handling of the data using interface injection. You can use the algorithmn for datastructures like array, associative arrays or lists.
/**
* #param DataListAvalancheSortInterface $dataList
* #param DataRangeInterface $beginRange
* #param int $avalancheIndex
* #return bool
*/
public function startAvalancheSort(DataListAvalancheSortInterface $dataList)
{
$avalancheIndex = 0;
$rangeResult = $this->avalancheSort($dataList, $dataList->getFirstIdent(), $avalancheIndex);
if (!$dataList->isLastIdent($rangeResult->getStop())) {
do {
$avalancheIndex++;
$lastIdent = $rangeResult->getStop();
if ($dataList->isLastIdent($lastIdent)) {
$rangeResult = new $this->rangeClass();
$rangeResult->setStart($dataList->getFirstIdent());
$rangeResult->setStop($dataList->getLastIdent());
break;
}
$nextIdent = $dataList->getNextIdent($lastIdent);
$rangeFollow = $this->avalancheSort($dataList, $nextIdent, $avalancheIndex);
$rangeResult = $this->mergeAvalanche($dataList, $rangeResult, $rangeFollow);
} while (true);
}
return $rangeResult;
}
/**
* #param DataListAvalancheSortInterface $dataList
* #param DataRangeInterface $range
* #return DataRangeInterface
*/
protected function findRun(DataListAvalancheSortInterface $dataList,
$startIdent)
{
$result = new $this->rangeClass();
$result->setStart($startIdent);
$result->setStop($startIdent);
do {
if ($dataList->isLastIdent($result->getStop())) {
break;
}
$nextIdent = $dataList->getNextIdent($result->getStop());
if ($dataList->oddLowerEqualThanEven(
$dataList->getDataItem($result->getStop()),
$dataList->getDataItem($nextIdent)
)) {
$result->setStop($nextIdent);
} else {
break;
}
} while (true);
return $result;
}
/**
* #param DataListAvalancheSortInterface $dataList
* #param $beginIdent
* #param int $avalancheIndex
* #return DataRangeInterface|mixed
*/
protected function avalancheSort(DataListAvalancheSortInterface $dataList,
$beginIdent,
int $avalancheIndex = 0)
{
if ($avalancheIndex === 0) {
$rangeFirst = $this->findRun($dataList, $beginIdent);
if ($dataList->isLastIdent($rangeFirst->getStop())) {
// it is the last run
$rangeResult = $rangeFirst;
} else {
$nextIdent = $dataList->getNextIdent($rangeFirst->getStop());
$rangeSecond = $this->findRun($dataList, $nextIdent);
$rangeResult = $this->mergeAvalanche($dataList, $rangeFirst, $rangeSecond);
}
} else {
$rangeFirst = $this->avalancheSort($dataList,
$beginIdent,
($avalancheIndex - 1)
);
if ($dataList->isLastIdent($rangeFirst->getStop())) {
$rangeResult = $rangeFirst;
} else {
$nextIdent = $dataList->getNextIdent($rangeFirst->getStop());
$rangeSecond = $this->avalancheSort($dataList,
$nextIdent,
($avalancheIndex - 1)
);
$rangeResult = $this->mergeAvalanche($dataList, $rangeFirst, $rangeSecond);
}
}
return $rangeResult;
}
protected function mergeAvalanche(DataListAvalancheSortInterface $dataList, $oddListRange, $evenListRange)
{
$resultRange = new $this->rangeClass();
$oddNextIdent = $oddListRange->getStart();
$oddStopIdent = $oddListRange->getStop();
$evenNextIdent = $evenListRange->getStart();
$evenStopIdent = $evenListRange->getStop();
$dataList->initNewListPart($oddListRange, $evenListRange);
do {
if ($dataList->oddLowerEqualThanEven(
$dataList->getDataItem($oddNextIdent),
$dataList->getDataItem($evenNextIdent)
)) {
$dataList->addListPart($oddNextIdent);
if ($oddNextIdent === $oddStopIdent) {
$restTail = $evenNextIdent;
$stopTail = $evenStopIdent;
break;
}
$oddNextIdent = $dataList->getNextIdent($oddNextIdent);
} else {
$dataList->addListPart($evenNextIdent);
if ($evenNextIdent === $evenStopIdent) {
$restTail = $oddNextIdent;
$stopTail = $oddStopIdent;
break;
}
$evenNextIdent = $dataList->getNextIdent($evenNextIdent);
}
} while (true);
while ($stopTail !== $restTail) {
$dataList->addListPart($restTail);
$restTail = $dataList->getNextIdent($restTail);
}
$dataList->addListPart($restTail);
$dataList->cascadeDataListChange($resultRange);
return $resultRange;
}
}
My algorithm with test code of java version. If you want to use it in your project you can define a comparator yourself.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
public class FileNameSortTest {
private static List<String> names = Arrays.asList(
"A__01__02",
"A__2__02",
"A__1__23",
"A__11__23",
"A__3++++",
"B__1__02",
"B__22_13",
"1_22_2222",
"12_222_222",
"2222222222",
"1.sadasdsadsa",
"11.asdasdasdasdasd",
"2.sadsadasdsad",
"22.sadasdasdsadsa",
"3.asdasdsadsadsa",
"adsadsadsasd1",
"adsadsadsasd10",
"adsadsadsasd3",
"adsadsadsasd02"
);
public static void main(String...args) {
List<File> files = new ArrayList<>();
names.forEach(s -> {
File f = new File(s);
try {
if (!f.exists()) {
f.createNewFile();
}
files.add(f);
} catch (IOException e) {
e.printStackTrace();
}
});
files.sort(Comparator.comparing(File::getName));
files.forEach(f -> System.out.print(f.getName() + " "));
System.out.println();
files.sort(new Comparator<File>() {
boolean caseSensitive = false;
int SPAN_OF_CASES = 'a' - 'A';
#Override
public int compare(File left, File right) {
char[] csLeft = left.getName().toCharArray(), csRight = right.getName().toCharArray();
boolean isNumberRegion = false;
int diff=0, i=0, j=0, lenLeft=csLeft.length, lenRight=csRight.length;
char cLeft = 0, cRight = 0;
for (; i<lenLeft && j<lenRight; i++, j++) {
cLeft = getCharByCaseSensitive(csLeft[i]);
cRight = getCharByCaseSensitive(csRight[j]);
boolean isNumericLeft = isNumeric(cLeft), isNumericRight = isNumeric(cRight);
if (isNumericLeft && isNumericRight) {
// Number start!
if (!isNumberRegion) {
isNumberRegion = true;
// Remove prefix '0'
while (i < lenLeft && cLeft == '0') i++;
while (j < lenRight && cRight == '0') j++;
if (i == lenLeft || j == lenRight) break;
}
// Diff start: calculate the diff value.
if (cLeft != cRight && diff == 0)
diff = cLeft - cRight;
} else {
if (isNumericLeft != isNumericRight) {
// One numeric and one char.
if (isNumberRegion)
return isNumericLeft ? 1 : -1;
return cLeft - cRight;
} else {
// Two chars: if (number) diff don't equal 0 return it.
if (diff != 0)
return diff;
// Calculate chars diff.
diff = cLeft - cRight;
if (diff != 0)
return diff;
// Reset!
isNumberRegion = false;
diff = 0;
}
}
}
// The longer one will be put backwards.
return (i == lenLeft && j == lenRight) ? cLeft - cRight : (i == lenLeft ? -1 : 1) ;
}
private boolean isNumeric(char c) {
return c >= '0' && c <= '9';
}
private char getCharByCaseSensitive(char c) {
return caseSensitive ? c : (c >= 'A' && c <= 'Z' ? (char) (c + SPAN_OF_CASES) : c);
}
});
files.forEach(f -> System.out.print(f.getName() + " "));
}
}
The output is,
1.sadasdsadsa 11.asdasdasdasdasd 12_222_222 1_22_2222 2.sadsadasdsad 22.sadasdasdsadsa 2222222222 3.asdasdsadsadsa A__01__02 A__11__23 A__1__23 A__2__02 A__3++++ B__1__02 B__22_13 adsadsadsasd02 adsadsadsasd1 adsadsadsasd10 adsadsadsasd3
1.sadasdsadsa 1_22_2222 2.sadsadasdsad 3.asdasdsadsadsa 11.asdasdasdasdasd 12_222_222 22.sadasdasdsadsa 2222222222 A__01__02 A__1__23 A__2__02 A__3++++ A__11__23 adsadsadsasd02 adsadsadsasd1 adsadsadsasd3 adsadsadsasd10 B__1__02 B__22_13
Process finished with exit code 0
// -1: s0 < s1; 0: s0 == s1; 1: s0 > s1
static int numericCompare(const string &s0, const string &s1) {
size_t i = 0, j = 0;
for (; i < s0.size() && j < s1.size();) {
string t0(1, s0[i++]);
while (i < s0.size() && !(isdigit(t0[0]) ^ isdigit(s0[i]))) {
t0.push_back(s0[i++]);
}
string t1(1, s1[j++]);
while (j < s1.size() && !(isdigit(t1[0]) ^ isdigit(s1[j]))) {
t1.push_back(s1[j++]);
}
if (isdigit(t0[0]) && isdigit(t1[0])) {
size_t p0 = t0.find_first_not_of('0');
size_t p1 = t1.find_first_not_of('0');
t0 = p0 == string::npos ? "" : t0.substr(p0);
t1 = p1 == string::npos ? "" : t1.substr(p1);
if (t0.size() != t1.size()) {
return t0.size() < t1.size() ? -1 : 1;
}
}
if (t0 != t1) {
return t0 < t1 ? -1 : 1;
}
}
return i == s0.size() && j == s1.size() ? 0 : i != s0.size() ? 1 : -1;
}
I am not very sure if it is you want, anyway, you can have a try:-)

A star algorithm with multiple goals [duplicate]

Let's consider a simple grid, where any point is connected with at most 4 other points (North-East-West-South neighborhood).
I have to write program, that computes minimal route from selected initial point to any of goal points, which are connected (there is route consisting of goal points between any two goals). Of course there can be obstacles on grid.
My solution is quite simple: I'm using A* algorithm with variable heuristic function h(x) - manhattan distance from x to nearest goal point. To find nearest goal point I have to do linear search (in O(n), where n - number of goal points). Here is my question: is there any more efficient solution (heuristic function) to dynamically find nearest goal point (where time < O(n))?
Or maybe A* is not good way to solve that problem?
How many goals, tens or thousands? If tens your way will work fine, if thousands then nearest neighbor search will give you ideas on setting up your data to search quickly.
The tradeoffs are obvious, spatially organizing your data to search will take time and on small sets brute force will be simpler to maintain. Since you're constantly evaluating I think that structuring the data will be worthwhile at very low numbers of points.
An alternate way to do this would be a modified flood fill algorithm that stops once it reaches a destination point during the flood.
First, decide whether you need to optimize, because any optimization is going to complicate your code, and for a small number of goals, your current solution is probably fine for a simple heuristic like Manhattan distance.
Before taking the first step, compute the heuristic for each goal. Remember the nearest goal as the currently selected goal, and move toward it, but subtract the maximum possible progress toward any goal from all the other distances. You can consider this second value a "meta-heuristic"; it is an optimistic estimate of the heuristic for other goals.
On subsequent steps, compute the heuristic for the current goal, and any goals with a "meta-heuristic" that is less than or equal to the heuristic. The other goals can't possibly have a better heuristic, so you don't need to compute them. The nearest goal becomes the new current goal; move toward it, subtracting the maximum possible progress from the others. Repeat until you arrive at a goal.
Use Dijkstra's algorithm, which has as it's output the minimal cost to all reachable points. Then you just select the goal points from the output.
you may consider this article If your goals not too much and want simple ways
If you want to search for any of several goals, construct a heuristic
h'(x) that is the minimum of h1(x), h2(x), h3(x), ... where h1, h2, h3
are heuristics to each of the nearby spots.
One way to think about this is that we can add a new zero-cost edge
from each of the goals to a new graph node. A path to that new node
will necessarily go through one of the goal nodes.
If you want to search for paths to all of several goals, your best
option may be Dijkstra’s Algorithm with early exit when you find all
the goals. There may be a variant of A* that can calculate these
paths; I don’t know.
If you want to search for spot near a single goal, ask A* search to
find a path to the center of the goal area. While processing nodes
from the OPEN set, exit when you pull a node that is near enough.
You can calculate the f score using the nearest target. As others said, for naive approach, you can directly calculate all target distance from current node and pick the minimum, if you only have few targets to search. For more than 100 targets, you can probably find the nearest by KDTree to speed up the process.
Here is a sample code in dart.
Iterable<Vector2> getPath(Vector2 from, Iterable<Vector2> targets,
{double? maxDistance, bool useAStar = false}) {
targets = targets.asSet();
clearPoints();
var projectedTargets = addPoints(targets).toSet();
var tree = useAStar ? IKDTree(targets) : null;
var q = PriorityQueue<Node>(_priorityQueueComparor);
Map<Vector2, Node> visited = {};
var node = Node(from);
visited[from] = node;
q.add(node);
while (q.isNotEmpty) {
var current = q.removeFirst();
// developer.log(
// '${current.point}#${current.distance}: ${getEdges(current.point).map((e) => e.dest)}');
for (var edge in getEdges(current.point)) {
if (visited.containsKey(edge.dest)) continue;
var distance = current.distance + edge.distance;
// too far
if (maxDistance != null && distance > maxDistance) continue;
// it is a target
if (projectedTargets.contains(edge.dest)) {
return reconstructPath(visited, current, edge.dest);
}
// we only interested in exploring polygon node.
if (!_polygonPoints.contains(edge.dest)) continue;
var f = 0.0;
if (tree != null) {
var nearest = tree
.nearest(edge.dest, maxDistance: maxDistance ?? double.infinity)
.firstOrNull;
f = nearest != null ? edge.dest.distanceToSquared(nearest) : 0.0;
}
node = Node(edge.dest, distance, current.count + 1, current.point, f);
visited[edge.dest] = node;
q.add(node);
}
}
return [];
}
Iterable<Vector2> reconstructPath(
Map<Vector2, Node> visited, Node prev, Vector2 point) {
var path = <Vector2>[point];
Node? currentNode = prev;
while (currentNode != null) {
path.add(currentNode.point);
currentNode = visited[currentNode.prev];
}
return path.reversed;
}
int _priorityQueueComparor(Node p0, Node p1) {
int r;
if (p0.f > 0 && p1.f > 0) {
r = ((p0.distance * p0.distance) + p0.f)
.compareTo((p1.distance * p1.distance) + p1.f);
if (r != 0) return r;
}
r = p0.distance.compareTo(p1.distance);
if (r != 0) return r;
return p0.count.compareTo(p1.count);
}
and the implementation of KDTree
class IKDTree {
final int _dimensions = 2;
late Node? _root;
IKDTree(Iterable<Vector2> points) {
_root = _buildTree(points, null);
}
Node? _buildTree(Iterable<Vector2> points, Node? parent) {
var list = points.asList();
if (list.isEmpty) return null;
var median = (list.length / 2).floor();
// Select the longest dimension as division axis
var axis = 0;
var aabb = AABB.fromPoints(list);
for (var i = 1; i < _dimensions; i++) {
if (aabb.range[i] > aabb.range[axis]) {
axis = i;
}
}
// Divide by the division axis and recursively build.
// var list = list.orderBy((e) => _selector(e)[axis]).asList();
list.sort(((a, b) => a[axis].compareTo(b[axis])));
var point = list[median];
var node = Node(point.clone());
node.parent = parent;
node.left = _buildTree(list.sublist(0, median), node);
node.right = _buildTree(list.sublist(median + 1), node);
update(node);
return node;
}
void addPoint(Vector2 point, [bool allowRebuild = true]) {
_root = _addByPoint(_root, point, allowRebuild, 0);
}
// void removePoint(Vector2 point, [bool allowRebuild = true]) {
// if (node == null) return;
// _removeNode(node, allowRebuild);
// }
Node? _addByPoint(
Node? node, Vector2 point, bool allowRebuild, int parentDim) {
if (node == null) {
node = Node(point.clone());
node.dimension = (parentDim + 1) % _dimensions;
update(node);
return node;
}
_pushDown(node);
if (point[node.dimension] < node.point[node.dimension]) {
node.left = _addByPoint(node.left, point, allowRebuild, node.dimension);
} else {
node.right = _addByPoint(node.right, point, allowRebuild, node.dimension);
}
update(node);
bool needRebuild = allowRebuild && criterionCheck(node);
if (needRebuild) node = rebuild(node);
return node;
}
// checked
void _pushDown(Node? node) {
if (node == null) return;
if (node.needPushDownToLeft && node.left != null) {
node.left!.treeDownsampleDeleted |= node.treeDownsampleDeleted;
node.left!.pointDownsampleDeleted |= node.treeDownsampleDeleted;
node.left!.treeDeleted =
node.treeDeleted || node.left!.treeDownsampleDeleted;
node.left!.deleted =
node.left!.treeDeleted || node.left!.pointDownsampleDeleted;
if (node.treeDownsampleDeleted) {
node.left!.downDeletedNum = node.left!.treeSize;
}
if (node.treeDeleted) {
node.left!.invalidNum = node.left!.treeSize;
} else {
node.left!.invalidNum = node.left!.downDeletedNum;
}
node.left!.needPushDownToLeft = true;
node.left!.needPushDownToRight = true;
node.needPushDownToLeft = false;
}
if (node.needPushDownToRight && node.right != null) {
node.right!.treeDownsampleDeleted |= node.treeDownsampleDeleted;
node.right!.pointDownsampleDeleted |= node.treeDownsampleDeleted;
node.right!.treeDeleted =
node.treeDeleted || node.right!.treeDownsampleDeleted;
node.right!.deleted =
node.right!.treeDeleted || node.right!.pointDownsampleDeleted;
if (node.treeDownsampleDeleted) {
node.right!.downDeletedNum = node.right!.treeSize;
}
if (node.treeDeleted) {
node.right!.invalidNum = node.right!.treeSize;
} else {
node.right!.invalidNum = node.right!.downDeletedNum;
}
node.right!.needPushDownToLeft = true;
node.right!.needPushDownToRight = true;
node.needPushDownToRight = false;
}
}
void _removeNode(Node? node, bool allowRebuild) {
if (node == null || node.deleted) return;
_pushDown(node);
node.deleted = true;
node.invalidNum++;
if (node.invalidNum == node.treeSize) {
node.treeDeleted = true;
}
// update and rebuild parent
var parent = node.parent;
if (parent != null) {
updateAncestors(parent);
bool needRebuild = allowRebuild && criterionCheck(parent);
if (needRebuild) parent = rebuild(parent);
}
}
void updateAncestors(Node? node) {
if (node == null) return;
update(node);
updateAncestors(node.parent);
}
void _removeByPoint(Node? node, Vector2 point, bool allowRebuild) {
if (node == null || node.treeDeleted) return;
_pushDown(node);
if (node.point == point && !node.deleted) {
node.deleted = true;
node.invalidNum++;
if (node.invalidNum == node.treeSize) {
node.treeDeleted = true;
}
return;
}
if (point[node.dimension] < node.point[node.dimension]) {
_removeByPoint(node.left, point, false);
} else {
_removeByPoint(node.right, point, false);
}
update(node);
bool needRebuild = allowRebuild && criterionCheck(node);
if (needRebuild) rebuild(node);
}
// checked
void update(Node node) {
var left = node.left;
var right = node.right;
node.treeSize = (left != null ? left.treeSize : 0) +
(right != null ? right.treeSize : 0) +
1;
node.invalidNum = (left != null ? left.invalidNum : 0) +
(right != null ? right.invalidNum : 0) +
(node.deleted ? 1 : 0);
node.downDeletedNum = (left != null ? left.downDeletedNum : 0) +
(right != null ? right.downDeletedNum : 0) +
(node.pointDownsampleDeleted ? 1 : 0);
node.treeDownsampleDeleted = (left == null || left.treeDownsampleDeleted) &&
(right == null || right.treeDownsampleDeleted) &&
node.pointDownsampleDeleted;
node.treeDeleted = (left == null || left.treeDeleted) &&
(right == null || right.treeDeleted) &&
node.deleted;
var minList = <Vector2>[];
var maxList = <Vector2>[];
if (left != null && !left.treeDeleted) {
minList.add(left.aabb.min);
maxList.add(left.aabb.max);
}
if (right != null && !right.treeDeleted) {
minList.add(right.aabb.min);
maxList.add(right.aabb.max);
}
if (!node.deleted) {
minList.add(node.point);
maxList.add(node.point);
}
if (minList.isNotEmpty && maxList.isNotEmpty) {
node.aabb = AABB()
..min = minList.min()
..max = maxList.max();
}
// TODO: Radius data for search: https://github.com/hku-mars/ikd-Tree/blob/main/ikd-Tree/ikd_Tree.cpp#L1312
if (left != null) left.parent = node;
if (right != null) right.parent = node;
// TODO: root alpha value for multithread
}
// checked
final minimalUnbalancedTreeSize = 10;
final deleteCriterionParam = 0.3;
final balanceCriterionParam = 0.6;
bool criterionCheck(Node node) {
if (node.treeSize <= minimalUnbalancedTreeSize) return false;
double balanceEvaluation = 0.0;
double deleteEvaluation = 0.0;
var child = node.left ?? node.right!;
deleteEvaluation = node.invalidNum / node.treeSize;
balanceEvaluation = child.treeSize / (node.treeSize - 1);
if (deleteEvaluation > deleteCriterionParam) return true;
if (balanceEvaluation > balanceCriterionParam ||
balanceEvaluation < 1 - balanceCriterionParam) return true;
return false;
}
void rebuildAll() {
_root = rebuild(_root);
}
// checked
Node? rebuild(Node? node) {
if (node == null) return null;
var parent = node.parent;
var points = flatten(node).toList();
// log('rebuilding: $node objects: ${objects.length}');
deleteTreeNodes(node);
return _buildTree(points, parent);
// if (parent == null) {
// _root = newNode;
// } else if (parent.left == node) {
// parent.left = newNode;
// } else if (parent.right == node) {
// parent.right = newNode;
// }
}
// checked
Iterable<Vector2> flatten(Node? node) sync* {
if (node == null) return;
_pushDown(node);
if (!node.deleted) yield node.point;
yield* flatten(node.left);
yield* flatten(node.right);
}
void deleteTreeNodes(Node? node) {
if (node == null) return;
_pushDown(node);
deleteTreeNodes(node.left);
deleteTreeNodes(node.right);
}
double _calcDist(Vector2 a, Vector2 b) {
double dist = 0;
for (var dim = 0; dim < _dimensions; dim++) {
dist += math.pow(a[dim] - b[dim], 2);
}
return dist;
}
// checked
double _calcBoxDist(Node? node, Vector2 point) {
if (node == null) return double.infinity;
double minDist = 0;
for (var dim = 0; dim < _dimensions; dim++) {
if (point[dim] < node.aabb.min[dim]) {
minDist += math.pow(point[dim] - node.aabb.min[dim], 2);
}
if (point[dim] > node.aabb.max[dim]) {
minDist += math.pow(point[dim] - node.aabb.max[dim], 2);
}
}
return minDist;
}
void _search(Node? node, int maxNodes, Vector2 point, BinaryHeap<Result> heap,
double maxDist) {
if (node == null || node.treeDeleted) return;
double curDist = _calcBoxDist(node, point);
double maxDistSqr = maxDist * maxDist;
if (curDist > maxDistSqr) return;
if (node.needPushDownToLeft || node.needPushDownToRight) {
_pushDown(node);
}
if (!node.deleted) {
double dist = _calcDist(point, node.point);
if (dist <= maxDistSqr &&
(heap.size() < maxNodes || dist < heap.peek().distance)) {
if (heap.size() >= maxNodes) heap.pop();
heap.push(Result(node, dist));
}
}
double distLeftNode = _calcBoxDist(node.left, point);
double distRightNode = _calcBoxDist(node.right, point);
if (heap.size() < maxNodes ||
distLeftNode < heap.peek().distance &&
distRightNode < heap.peek().distance) {
if (distLeftNode <= distRightNode) {
_search(node.left, maxNodes, point, heap, maxDist);
if (heap.size() < maxNodes || distRightNode < heap.peek().distance) {
_search(node.right, maxNodes, point, heap, maxDist);
}
} else {
_search(node.right, maxNodes, point, heap, maxDist);
if (heap.size() < maxNodes || distLeftNode < heap.peek().distance) {
_search(node.left, maxNodes, point, heap, maxDist);
}
}
} else {
if (distLeftNode < heap.peek().distance) {
_search(node.left, maxNodes, point, heap, maxDist);
}
if (distRightNode < heap.peek().distance) {
_search(node.right, maxNodes, point, heap, maxDist);
}
}
}
/// Find the [maxNodes] of nearest Nodes.
/// Distance is calculated via Metric function.
/// Max distance can be set with [maxDistance] param
Iterable<Vector2> nearest(Vector2 point,
{int maxNodes = 1, double maxDistance = double.infinity}) sync* {
var heap = BinaryHeap<Result>((e) => -e.distance);
_search(_root, maxNodes, point, heap, maxDistance);
var found = math.min(maxNodes, heap.content.length);
for (var i = 0; i < found; i++) {
yield heap.content[i].node.point;
}
}
int get length => _root?.length ?? 0;
int get height => _root?.height ?? 0;
}
class Result {
final Node node;
final double distance;
const Result(this.node, this.distance);
}
class Node {
Vector2 point;
int dimension = 0;
Node? parent;
Node? left;
Node? right;
int treeSize = 0;
int invalidNum = 0;
int downDeletedNum = 0;
bool deleted = false;
bool treeDeleted = false;
bool needPushDownToLeft = false;
bool needPushDownToRight = false;
bool treeDownsampleDeleted = false;
bool pointDownsampleDeleted = false;
AABB aabb = AABB();
Node(this.point);
int get length {
return 1 +
(left == null ? 0 : left!.length) +
(right == null ? 0 : right!.length);
}
int get height {
return 1 +
math.max(
left == null ? 0 : left!.height,
right == null ? 0 : right!.height,
);
}
int get depth {
return 1 + (parent == null ? 0 : parent!.depth);
}
}

Spoj brackets segment tree

can anyone help me in my code. I am getting WA and m not able to rectify it plzzz
my code http://ideone.com/DkrwIg
problem link : http://www.spoj.com/problems/BRCKTS/
i am a bit doubtful in my modification function.
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
char str[40010];
struct node
{
int sum;
int minsum;
}tree[1000005];
void build(int id,int l,int r)
{
if(r-l<2)
{
if(str[l] == '(')
{
tree[id].sum = 1;
tree[id].minsum = 1;
}
else
{
tree[id].sum = -1;
tree[id].minsum = -1;
}
return;
}
int mid = (r+l)/2;
build(id*2,l,mid);
build(id*2+1,mid,r);
tree[id].sum = tree[id*2].sum + tree[id*2+1].sum;
tree[id].minsum = min(tree[id*2].minsum,tree[id*2].minsum+tree[id*2+1].minsum);
}
void modify(int index,int id,int l,int r)
{
if(r-l<2)
{
tree[id].sum = tree[id].minsum = -tree[id].sum;
return;
}
int mid = (r+l)/2;
if(index<mid)
modify(index,id*2,l,mid);
else
modify(index,id*2+1,mid,r);
tree[id].sum = tree[id*2].sum + tree[id*2+1].sum;
tree[id].minsum = min(tree[id*2].minsum,tree[id*2].minsum+tree[id*2+1].minsum);
}
int main()
{
int n,k;
int val;
int h = 1;
for(int h=1;h<=10;h++)
{
scanf("%d",&n);
scanf("%s",str);
build(1,0,n);
//cout<<"Test "<<h<<" :"<<endl;
printf("Test %d:\n",h);
//cin>>k;
scanf("%d",&k);
while(k--)
{
cin>>val;
if(!val)
{
if(tree[1].sum == 0 && tree[1].minsum == 0)
{
//cout<<"YES"<<endl;
printf("YES\n");
}
else
{
//cout<<"NO"<<endl;
printf("NO\n");
}
//cout<<tree[1].sum<<"------------"<<tree[1].minsum<<endl;
}
else
{
modify(val-1,1,0,n);
}
}
}
return 0;
}

infix to postfix conversion program(java)

I was working on a infix to postfix program(using stacks) but after all those efforts, something went wrong somewhere.I am getting the output as infix without conversion, please check if my intopost method is correct or not.
//stack class also containing the intopostfix method
import java.util.*;
public class Stack
{ int i,j;
char postfix[];
char stack[];
int top;
String post;
public Stack(int n)
{
stack=new char[n];
top=-1;
}
public void push(char item)
{
if(top>=stack.length)
System.out.println("Stack overflow");
else
{
stack[++top]=item;
}
}
public char pop()
{
if(top==-1)
{ System.out.println("Stack underflow");
return 0;
}
else
return stack[top--];
}
boolean isAlpha(char ch)
{
if((ch>='a'&&ch<='z')||(ch>=0&&ch<='9'))
return true;
else
return false;
}
boolean isOperator(char ch)
{
if(ch=='+'||ch=='-'||ch=='*'||ch=='/')
return true;
else return false;
}
void intopost(String str)
{
postfix=new char[str.length()];
char ch;
j=0;
for(i=0;i<str.length();i++)
{
ch=str.charAt(i);
if(ch=='(')
push(ch);
else if(isAlpha(ch))
{
postfix[j++]=ch;
}
else if(isOperator(ch))
{
push (ch);
}
else if(ch==')')
{
while((pop())!='(')
{
postfix[j++]=pop();
}
}
}
}
void disp()
{
for(i=0;i<postfix.length;i++)
{
System.out.print(postfix[i]);
}
}
}
at first change the following line
if((ch>='a'&&ch<='z')||(ch>=0&&ch<='9'))
into
if((ch>='a'&&ch<='z')||(ch>='0' &&ch<='9'))
And then
else if(ch==')')
{
while((pop())!='(')
{
postfix[j++]=pop();
}
}
here you are calling the pop function twice. this causes your stack to underflow.
that should be called once.
and finally try the following
void intopost(String str)
{
postfix=new char[str.length()];
char ch;
j=0;
for(i=0;i<str.length();i++)
{
ch=str.charAt(i);
if(ch=='(')
push(ch);
else if(isAlpha(ch))
{
postfix[j++]=ch;
}
else if(isOperator(ch))
{
push (ch);
}
else if(ch==')')
{
char c = pop();
while(c!='(')
{
postfix[j++]=c;
c= pop();
}
}
}
}
Following program would do the job for you
import java.io.*;
class stack
{
char stack1[]=new char[20];
int top;
void push(char ch)
{
top++;
stack1[top]=ch;
}
char pop()
{
char ch;
ch=stack1[top];
top--;
return ch;
}
int pre(char ch)
{
switch(ch)
{
case '-':return 1;
case '+':return 1;
case '*':return 2;
case '/':return 2;
}
return 0;
}
boolean operator(char ch)
{
if(ch=='/'||ch=='*'||ch=='+'||ch=='-')
return true;
else
return false;
}
boolean isAlpha(char ch)
{
if(ch>='a'&&ch<='z'||ch>='0'&&ch=='9')
return true;
else
return false;
}
void postfix(String str)
{
char output[]=new char[str.length()];
char ch;
int p=0,i;
for(i=0;i<str.length();i++)
{
ch=str.charAt(i);
if(ch=='(')
{
push(ch);
}
else if(isAlpha(ch))
{
output[p++]=ch;
}
else if(operator(ch))
{
if(stack1[top]==0||(pre(ch)>pre(stack1[top]))||stack1[top]=='(')
{
push(ch);
}
}
else if(pre(ch)<=pre(stack1[top]))
{
output[p++]=pop();
push(ch);
}
else if(ch=='(')
{
while((ch=pop())!='(')
{
output[p++]=ch;
}
}
}
while(top!=0)
{
output[p++]=pop();
}
for(int j=0;j<str.length();j++)
{
System.out.print(output[j]);
}
}
}
class intopost
{
public static void main(String[] args)throws Exception
{
String s;
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
stack b=new stack();
System.out.println("Enter input string");
s=br.readLine();
System.out.println("Input String:"+s);
System.out.println("Output String:");
b.postfix(s);
}
}
Output:
Enter input string
a+b*c
Input String:a+b*c
Output String:
abc*+
Enter input string
a+(b*c)/d
Input String:a+(b*c)/d
Output String:
abc*d/)(+
public class InfixToPostfix
{
private Stack stack;
private String infix;
private String output = "";
public InfixToPostfix(String input)
{
infix = input;
stack = new Stack(infix.length());
}
public String convertInfixToPostfix()
{
for(int index=0; index < infix.length(); index++)
{
char itemRead = infix.charAt(index);
switch(itemRead)
{
case '+':
case '-':
processOperator(itemRead, 1);
break;
case '*':
case '/':
processOperator(itemRead, 2);
break;
case '(':
stack.push(itemRead);
break;
case ')':
popStackTillOpenParenthesis();
break;
default:
output = output + itemRead;
break;
}
}
while( !stack.isEmpty() )
{
output = output + stack.pop();
}
return output;
}
public void processOperator(char infixOperator, int precedence)
{
while( !stack.isEmpty() )
{
char popedOpr = stack.pop();
if( popedOpr == '(' )
{
stack.push(popedOpr);
break;
}
else
{
int popedOprPrecedence;
if(popedOpr == '+' || popedOpr == '-')
popedOprPrecedence = 1;
else
popedOprPrecedence = 2;
if(popedOprPrecedence < precedence)
{
stack.push(popedOpr);
break;
}
else
output = output + popedOpr;
}
}
stack.push(infixOperator);
}
public void popStackTillOpenParenthesis()
{
while(!stack.isEmpty())
{
char popedOpr = stack.pop();
if( popedOpr == '(' )
break;
else
output = output + popedOpr;
}
}
}
Explanation of postfix notation, with algorithm and example is present at: http://www.thinkscholar.com/java/java-topics/infix-to-postfix/
http://www.thinkscholar.com/java/java-topics/infix-to-postfix/
Try this code
/**
* Checks if the input is operator or not
* #param c input to be checked
* #return true if operator
*/
private boolean isOperator(char c){
if(c == '+' || c == '-' || c == '*' || c =='/' || c == '^')
return true;
return false;
}
/**
* Checks if c2 has same or higher precedence than c1
* #param c1 first operator
* #param c2 second operator
* #return true if c2 has same or higher precedence
*/
private boolean checkPrecedence(char c1, char c2){
if((c2 == '+' || c2 == '-') && (c1 == '+' || c1 == '-'))
return true;
else if((c2 == '*' || c2 == '/') && (c1 == '+' || c1 == '-' || c1 == '*' || c1 == '/'))
return true;
else if((c2 == '^') && (c1 == '+' || c1 == '-' || c1 == '*' || c1 == '/'))
return true;
else
return false;
}
/**
* Converts infix expression to postfix
* #param infix infix expression to be converted
* #return postfix expression
*/
public String convert(String infix){
String postfix = ""; //equivalent postfix is empty initially
Stack<Character> s = new Stack<>(); //stack to hold symbols
s.push('#'); //symbol to denote end of stack
for(int i = 0; i < infix.length(); i++){
char inputSymbol = infix.charAt(i); //symbol to be processed
if(isOperator(inputSymbol)){ //if a operator
//repeatedly pops if stack top has same or higher precedence
while(checkPrecedence(inputSymbol, s.peek()))
postfix += s.pop();
s.push(inputSymbol);
}
else if(inputSymbol == '(')
s.push(inputSymbol); //push if left parenthesis
else if(inputSymbol == ')'){
//repeatedly pops if right parenthesis until left parenthesis is found
while(s.peek() != '(')
postfix += s.pop();
s.pop();
}
else
postfix += inputSymbol;
}
//pops all elements of stack left
while(s.peek() != '#'){
postfix += s.pop();
}
return postfix;
}
This is taken from my blog here. Visit to get the complete code and see the each step of conversion in detail . Also note that here both parenthesis and exponent are also considered and can convert any expression.
try this code, more efficient as here i am not making use of lots of methods in this, just the main method.
package inn;
import com.sun.org.apache.bcel.internal.generic.GOTO;
import java.util.Scanner;
/**
*
* #author MADMEN
*/
public class Half_Life {
public Half_Life()
{
// a+b*c
// a*b+c
// d/e*c+2
// d/e*(c+2)
// (a+b)*(c-d)
// (a+b-c)*d/f
// (a+b)*c-(d-e)^(f+g)
// (4+8)*(6-5)/((3-2)*(2+2))
//(300+23)*(43-21)/(84+7) -> 300 23+43 21-*84 7+/
}
public static void main(String[] args)
{
System.out.print("\n Enter Expression : ");
Scanner c=new Scanner(System.in);
String exp=c.next();
int sym_top=0,po_top=-1,p=0,p2=0;
int size=exp.length();
char a[]=exp.toCharArray();
char symbols[]=new char[size];
char pfix[]=new char[size];
symbols[sym_top]='$';
for(int i=0;i<size;i++)
{
char c1=a[i];
if(c1==')')
{
while(sym_top!=0)
{
if(symbols[sym_top]=='(')
break;
pfix[++po_top]=symbols[sym_top--];
}
sym_top--;
}
else if(c1=='(')
{
symbols[++sym_top]=c1;
}
else if(c1=='+' || c1=='-' || c1=='*' || c1=='/' || c1=='^')
{
switch(c1)
{
case '+':
case '-': p=2;
break;
case '*':
case '/': p=4;
break;
case '^': p=5;
break;
default: p=0;
}
if(sym_top<1)
{
symbols[++sym_top]=c1;
}
else
{
do
{
char c2=symbols[sym_top];
if(c2=='^')
{
p2=5;
}
else if(c2=='*' || c2=='/')
{
p2=4;
}
else if(c2=='+' || c2=='-')
{
p2=2;
}
else
{
p2=1;
}
if(p2>=p)
{
pfix[++po_top]=symbols[sym_top--];
}
if(p>p2 || symbols[sym_top]=='$')
{
symbols[++sym_top]=c1;
break;
}
}while(sym_top!=-1);
}
}
else
{
pfix[++po_top]=c1;
}
}
for(;sym_top>0;sym_top--)
{
pfix[++po_top]=symbols[sym_top];
}
System.out.print("\n Infix to Postfix expression : ");
for(int j=0;j<=po_top;j++)
{
System.out.print(pfix[j]);
}
System.out.println("\n");
}
}
check the extreme last brace.
you can ask for more Data Structures programs at : sankie2902#gmail.com

Resources