Hello I don't know what is wrong with my BST insert method.
Any suggestions it has too be non recursive it adds to the right always I want to know why it adds to the ends to the BST when I print it shows that the nodes were added at the right only.
void InsertBST(LZWCmp cmp, TreeNode **root, int code)
{
TreeNode tmp = *root;
TreeNode current = NULL;
Code temp;
Code temp1;
int size;
int comp;
int direction = -1;
if(*root == NULL)
root = CreateNode(code)
while(tmp != NULL) {
temp = GetCode(cmp->cst, tmp->cNum);
temp1 = GetCode(cmp->cst, code);
size = temp.size;
if(temp1.size < temp.size)
size = temp1.size;
comp = memcmp(temp1.data, temp.data, size);
if(temp1.size < temp.size && comp == 0)
comp = -1;
else if(temp1.size < temp.size && comp == 0)
comp = 1;
if(comp < 0) {
current = tmp;
direction = FALSE;
tmp = tmp->left;
} else (
current = tmp;
direction = TRUE;
tmp = tmp->right;
}
}
if(direction == FALSE)
current->left = CreateNode(code);
else
current->right = CreateNode(code);
}
There you go:
void InsertBST(LZWCmp cmp, TreeNode **root, int code)
{
Code temp;
Code temp1;
int size;
int comp;
while ( *root ) {
temp = GetCode(cmp->cst, (*root)->cNum);
temp1 = GetCode(cmp->cst, code);
size = (temp1.size < temp.size) ? temp1.size : temp.size;
comp = memcmp(temp1.data, temp.data, size);
if (comp ==0 ) comp = (temp1.size < temp.size ) ? -1 : 1;
root = (comp < 0) ? &(*root)->left
: &(*root)->right;
}
*root = CreateNode(code);
}
NOTE: this code does not check for duplicates. It always inserts a node.
NOTE2: I am not sure about the sign in: if (comp ==0 ) comp = (temp1.size < temp.size ) ? -1 : 1; (in the original the sign was the same in both cases)
Related
I have a condition which checks if the latest fast moving average value is above or below the slow moving average and if the bid price is above or below the fast ma.
But I am getting this compile error:
The iMA function is returning data.
Here is my code:
int fast_ma_handle;
int slow_ma_handle;
int OnInit()
{
fast_ma_handle = iMA(_Symbol,_Period,8,0,MODE_EMA,PRICE_CLOSE);
slow_ma_handle = iMA(_Symbol,_Period,21,0,MODE_EMA,PRICE_CLOSE);
return(INIT_SUCCEEDED);
}
void OnDeinit(const int reason)
{
}
void OnTick()
{
double fast_ma_array[], slow_ma_array[];
int copied1 = CopyBuffer(fast_ma_handle,0,0,1,fast_ma_array);
int copied2 = CopyBuffer(slow_ma_handle,0,0,1,slow_ma_array);
double bid_price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
int trend_direction = 0;
if(fast_ma_array[0] > slow_ma_array[0] && bid_price > fast_ma_array)
trend_direction = 1;
else if(fast_ma_array[0] < slow_ma_array[0] && bid_price < fast_ma_array)
trend_direction = -1;
}
Thanks
You have a couple of mistakes in your code. I've corrected it for you.
int fast_ma_handle;
int slow_ma_handle;
int OnInit()
{
fast_ma_handle = iMA(_Symbol,_Period,8,0,MODE_EMA,PRICE_CLOSE);
slow_ma_handle = iMA(_Symbol,_Period,21,0,MODE_EMA,PRICE_CLOSE);
return(INIT_SUCCEEDED);
}
void OnTick()
{
double fast_ma_array[], slow_ma_array[];
ArraySetAsSeries(fast_ma_array, true);
ArraySetAsSeries(slow_ma_array, true);
int copied1 = CopyBuffer(fast_ma_handle,0,0,100,fast_ma_array);
int copied2 = CopyBuffer(slow_ma_handle,0,0,100,slow_ma_array);
double bid_price = SymbolInfoDouble(_Symbol,SYMBOL_BID);
int trend_direction = 0;
if(fast_ma_array[0] > slow_ma_array[0] && bid_price > fast_ma_array[0])
trend_direction = 1;
else if(fast_ma_array[0] < slow_ma_array[0] && bid_price < fast_ma_array[0])
trend_direction = -1;
}
I have 6 documents each with the format below
Header
Text
table 1
Bullet Points
table 2
Text
I want to combine them into one doc - however when I tried this code it dose not work.Please if anyone can advise please
`
function mergeDocs() {
var docIDs = ['list-of','documents','ids','you should have somehow'];
var baseDoc = DocumentApp.openById(docIDs[0]);
var body = baseDoc.getActiveSection();
for( var i = 1; i < docIDs.length; ++i ) {
var otherBody = DocumentApp.openById(docIDs[i]).getActiveSection();
var totalElements = otherBody.getNumChildren();
for( var j = 0; j < totalElements; ++j ) {
var element = otherBody.getChild(j).copy();
var type = element.getType();
if( type == DocumentApp.ElementType.PARAGRAPH )
body.appendParagraph(element);
else if( type == DocumentApp.ElementType.TABLE )
body.appendTable(element);
else if( type == DocumentApp.ElementType.LIST_ITEM )
body.appendListItem(element);
else
throw new Error("According to the doc this type couldn't appear in the body: "+type);
}
}
`
Lets say I have a table with a list of names, such as "a, b, c" and each name has several other values assigned (some of the other values can be assigned to several/all of names values, example below).
Table example:
( names - other ):
a - aa
a - ab
a - ac
b - ab
b - bb
b - cb
c - ac
c - bc
c - cc
How do I make in birt so that I could select names in one parameter box and get corresponding other values to select for another parameter? I know it's possible to do that with cascading parameter, but that doesn't allow to have multiselect for the first parameter, which in our example would be names values.
Found a solution partly here: https://forums.opentext.com/forums/developer/discussion/61283/allow-multi-value-for-cascading-parameter
and here (thanks google translate ^^): https://www.developpez.net/forums/d1402270/logiciels/solutions-d-entreprise/business-intelligence/birt/birt-4-3-1-multi-value-cascade-parameters/
Steps to do:
change"\birt\webcontent\birt\ajax\ui\dialog\BirtParameterDialog.js" file contents (there is a file to download for replacement in one of the links, but in case it goes dead I'm sharing 2 snippets from it where the changes occur:
__refresh_cascade_select : function( element )
{
var matrix = new Array( );
var m = 0;
for( var i = 0; i < this.__cascadingParameter.length; i++ )
{
for( var j = 0; j < this.__cascadingParameter[i].length; j++ )
{
var paramName = this.__cascadingParameter[i][j].name;
if( paramName == this.__isnull )
paramName = this.__cascadingParameter[i][j].value;
if( paramName == element.id.substr( 0, element.id.length - 10 ) )
{
//CHANGE//
//The two way work (String(selectedValue) or Array(SelectedValueArray))
var l = 0;
var isFirstElement = true;
var selectedValue = "";
var selectedValueArray = new Array();
for(var test = 0; test<element.options.length;test++){
if(element.options[test].selected){
if(isFirstElement){
isFirstElement = false;
selectedValue = element.options[test].value;
}
else{
selectedValue = selectedValue+","+element.options[test].value;
}
selectedValueArray[l] = element.options[test].value;
l++;
}
}
//CHANGE//
var tempText = element.options[element.selectedIndex].text;
var tempValue = element.options[element.selectedIndex].value;
// Null Value Parameter
if ( tempValue == Constants.nullValue )
{
this.__cascadingParameter[i][j].name = this.__isnull;
this.__cascadingParameter[i][j].value = paramName;
}
else if( tempValue == '' )
{
if( tempText == "" )
{
var target = element;
target = target.parentNode;
var oInputs = target.getElementsByTagName( "input" );
if( oInputs.length >0 && oInputs[1].value != Constants.TYPE_STRING )
{
// Only String parameter allows blank value
alert( birtUtility.formatMessage( Constants.error.parameterNotAllowBlank, paramName ) );
this.__clearSubCascadingParameter( this.__cascadingParameter[i], j );
return;
}
else
{
// Blank Value
this.__cascadingParameter[i][j].name = paramName;
this.__cascadingParameter[i][j].value = tempValue;
}
}
else
{
// Blank Value
this.__cascadingParameter[i][j].name = paramName;
this.__cascadingParameter[i][j].value = tempValue;
}
}
else
{
this.__cascadingParameter[i][j].name = paramName;
//CHANGE//
//The two way work (String(selectedValue) or Array(SelectedValueArray))
this.__cascadingParameter[i][j].value = selectedValueArray;
//CHANGE//
}
for( var m = 0; m <= j; m++ )
{
if( !matrix[m] )
{
matrix[m] = {};
}
matrix[m].name = this.__cascadingParameter[i][m].name;
matrix[m].value = this.__cascadingParameter[i][m].value;
}
this.__pendingCascadingCalls++;
birtEventDispatcher.broadcastEvent( birtEvent.__E_CASCADING_PARAMETER, matrix );
}
}
}
},
and this:
// exist select control and input text/password
// compare the parent div offsetTop
if( oFirstITC.parentNode && oFirstST.parentNode )
{
// Bugzilla 265615: need to use cumulative offset for special cases
// where one element is inside a group container
var offsetITC = Position.cumulativeOffset( oFirstITC );
var offsetST = Position.cumulativeOffset( oFirstST );
// compare y-offset first, then x-offset to determine the visual order
if( ( offsetITC[1] > offsetST[1] ) || ( offsetITC[1] == offsetST[1] && offsetITC[0] > offsetST[0] ) )
{
oFirstST.focus( );
}
else
{
oFirstITC.focus( );
}
}
After .js is changed cascading parameters can have multiselect on all levels.
Example:
1st DataSet "DS_country" query:
select CLASSICMODELS.OFFICES.COUNTRY
from CLASSICMODELS.OFFICES
2nd DataSet "DS_office" query:
select CLASSICMODELS.OFFICES.OFFICECODE
from CLASSICMODELS.OFFICES
where CLASSICMODELS.OFFICES.COUNTRY IN ('DS_country')
After datasets are created we can make cascading report parameters CRP_country and CRP_office (keep in mind that UI doesn't let you to choose "Allow multiple values" on the upper levels, but we can change that in property editor after the parameters are made by going to advanced tab and changing "Scalar parameter type" property value to "Multi Value")
The only thing left is to pick lower level cascading parameters (CRP_office in our example) and go to script tab and add this on "beforeOpen":
// Do that if your selections are in String type.
var stringArray = params["CRP_country"].value.toString().split(",");
var result = "";
for(var i =0 ; i < stringArray.length ; i++){
if(i==0){
result = "'"+stringArray[i]+"'";
}
else{
result = result+",'"+stringArray[i]+"'";
}
}
// For String
this.queryText = this.queryText.replace("'DS_country'", result);
//For integer (the first part is useless)
//this.queryText = this.queryText.replace("'DS_country'",
params["CRP_country"].value);
I need to make a module that allow the user to enter width and height , and then it should calculate the price based on the height and width .
thanks in advance
let's say that you want to do it on the product ID N° 1 from the product page :
first add two inputs fields in your product.tpl ( or in your module.tpl called in product.tpl)
<input name="height"><br>
<input name="width">
now you need to get it in your module.php to change the price dynamicly :
$id_product = 1;
$newPrice = 0;
$height = Tools::getValue('height');
$width = Tools::getValue('width');
//Price rules (change with your rules)
if($height > 10 && $width > 10) $newPrice = 10;
$specific_price = new SpecificPrice();
$specific_price->price = $newPrice;
$specific_price->id_cart = (int) $this->context->cart->id;
$specific_price->id_shop = 0;
$specific_price->id_shop_group = 0;
$specific_price->id_currency = 0;
$specific_price->id_country = 0;
$specific_price->id_group = 0;
$specific_price->id_customer = (int) $this->context->customer->id;
$specific_price->id_product = (int)$id_product;
$specific_price->id_product_attribute = 0;
$specific_price->from_quantity = 1;
$specific_price->reduction = 0;
$specific_price->reduction_type = 'amount';
$specific_price->from = '0000-00-00 00:00:00';
$specific_price->to = '0000-00-00 00:00:00';
$specific_price->add();
and if you want add it to cart
$cart->id_lang = (int)($this->context->cookie->id_lang);
$cart->id_currency = (int)($this->context->cookie->id_currency);
$cart->updateQty($qte, $id_product);
and after order is done you put the normal price, so override the orderConfirmation controller in override/controllers/front/OrderConfirmationController.php:
class OrderConfirmationController extends OrderConfirmationControllerCore
{
public $ssl = true;
public $php_self = 'order-confirmation';
public $id_cart;
public $id_module;
public $id_order;
public $reference;
public $secure_key;
public function getPriceBack($id_product){
$normalPrice = Product::getPriceStatic($id_product);
$specific_price = new SpecificPrice();
$specific_price->price = $normalPrice;
$specific_price->id_cart = (int) $this->context->cart->id;
$specific_price->id_shop = 0;
$specific_price->id_shop_group = 0;
$specific_price->id_currency = 0;
$specific_price->id_country = 0;
$specific_price->id_group = 0;
$specific_price->id_customer = (int) $this->context->customer->id;
$specific_price->id_product = (int)$id_product;
$specific_price->id_product_attribute = 0;
$specific_price->from_quantity = 1;
$specific_price->reduction = 0;
$specific_price->reduction_type = 'amount';
$specific_price->from = '0000-00-00 00:00:00';
$specific_price->to = '0000-00-00 00:00:00';
$specific_price->add();
}
public function init()
{
parent::init();
$this->id_cart = (int)(Tools::getValue('id_cart', 0));
$is_guest = false;
/* get normal price back */
$id_product = 1;
self::getPriceBack($id_product);
/* check if the cart has been made by a Guest customer, for redirect link */
if (Cart::isGuestCartByCartId($this->id_cart)) {
$is_guest = true;
$redirectLink = 'index.php?controller=guest-tracking';
} else {
$redirectLink = 'index.php?controller=history';
}
$this->id_module = (int)(Tools::getValue('id_module', 0));
$this->id_order = Order::getOrderByCartId((int)($this->id_cart));
$this->secure_key = Tools::getValue('key', false);
$order = new Order((int)($this->id_order));
if ($is_guest) {
$customer = new Customer((int)$order->id_customer);
$redirectLink .= '&id_order='.$order->reference.'&email='.urlencode($customer->email);
}
if (!$this->id_order || !$this->id_module || !$this->secure_key || empty($this->secure_key)) {
Tools::redirect($redirectLink.(Tools::isSubmit('slowvalidation') ? '&slowvalidation' : ''));
}
$this->reference = $order->reference;
if (!Validate::isLoadedObject($order) || $order->id_customer != $this->context->customer->id || $this->secure_key != $order->secure_key) {
Tools::redirect($redirectLink);
}
$module = Module::getInstanceById((int)($this->id_module));
if ($order->module != $module->name) {
Tools::redirect($redirectLink);
}
}
}
after the order is done you have to empty the cart with id_product and delete rule in dbb :
$this->context->cart->deleteProduct(1);
Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'specific_price WHERE id_customer='.(int)$this->context->customer->id);
it s just an example and can not use without variables tests and maybe put constante for your product id concerned, hope it helps
The TreeNode class is defined with only left and right child.
public class TreeNode {
public int val;
public TreeNode left, right;
public TreeNode(int val) {
this.val = val;
}
}
My code finds the next lowest node in O(n). I was wondering if it's possible to find it in lg(N) given that the node doesn't have a pointer to its parent node.
// run time O(n)
public static Integer findNextLowest(TreeNode root, int target) {
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || stack.size() > 0) {
while (cur != null) {
stack.push(cur);
cur = cur.right;
}
TreeNode node = stack.pop();
if (node.val < target) return node.val; // found the next lowest
cur = node.left;
}
return null;
}
private static TreeNode findNextLowest(TreeNode root, int target){
TreeNode node = root;
TreeNode res = null;
while(node != null){
while(node != null && node.val >= target){
node = node.left;
}
while(node != null && node.val < target){
res = node;
node = node.right;
}
}
return res;
}
No, because you haven't implemented a Binary Search Tree, just a Binary Tree.
A BST will constrain its values such that left.val < val < right.val, so you can do
// run time O(log(n)) if cur is balanced
public static Integer findNextLowest(TreeNode cur, int target) {
if (target < cur.val) { return cur.left != null ? findNextLowest(cur.left, target) : null; }
if (curr.right != null)
{
Integer result = findNextLowest(cur.right, target);
if (result != null) { return result; }
}
return cur.val;
}
You should use something like a R-B tree to ensure it is balanced