- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在为一个项目用c创建一个布尔代数简化器。为了简化布尔代数表达式,我采用以下方法:
1)简化每个变量的NOT,并在适用的情况下应用德摩根定律
2)简化表达式中的括号(如果有)
3)展开表达式中可以展开的任何括号
4)简化表达式中的每个项,例如,对于表达式A+B•A,B•A将是一个项。术语被拆分,因此每个术语只包含一个gate-and,or,xor。NOT应用于这些变量,并在与数组中每个变量的索引相对应的列表中表示。例如,nots[0]包含表达式中第一个变量上的nots数。在我的程序中,此时没有变量通过not门连接。
5)尽可能保理
6)如果表达式不能进行因子分解,则将其简化。如果已将其分解,则重复步骤2之后的步骤,直到表达式在执行步骤时没有更改为止。
我无法创建一个对所有/大多数情况都有效的析因子程序。我已经创建了一个分解子例程并将其放在下面。我尝试使它只扩展两个括号的最大值,括号中没有括号,以便使子程序更容易创建。然而,创建这样的算法对我来说是相当困难的。
如果有人能提供一些伪代码,或解释如何创建这样的算法,指出我的代码中的错误,甚至提供一些代码,我可以分析和理解,我将非常感谢。代码如下所示:(警告:由于缺乏经验,编程非常糟糕。)
private bool Factorise(ref List<string> Expression, ref List<int> NOTsNew)
{
string PreviousExpression = convertexpressionlisttostring(Expression);
// loop and get each indiviual variable - no duplicates
// loop through expression for every variable and see if it occurs more than once
List<List<string>> itemsthatappearwithinexpression = new List<List<string>>();
List<string> charactersthatappearwithinexpression = new List<string>();
List<string> Notsofcharactersthathappearwithinexpression = new List<string>();
List<string> numberoftimescharacterappears = new List<string>();
List<string> positionofitemswithinexpression = new List<string>();
itemsthatappearwithinexpression.Add(charactersthatappearwithinexpression);
itemsthatappearwithinexpression.Add(Notsofcharactersthathappearwithinexpression);
itemsthatappearwithinexpression.Add(positionofitemswithinexpression);
itemsthatappearwithinexpression.Add(numberoftimescharacterappears);
for (int i = 0; i < Expression.Count; i++)
{
if (Expression[i] != "•" && Expression[i] != "+" && Expression[i] != "⊕")
{
if (itemsthatappearwithinexpression[0].Count == 0)
{
itemsthatappearwithinexpression[0].Add(Expression[i]);
itemsthatappearwithinexpression[1].Add(NOTsNew[i].ToString());
itemsthatappearwithinexpression[2].Add(i.ToString());
}
bool matched = false;
for (int y = 0; y < itemsthatappearwithinexpression[0].Count; y++)
{
if (itemsthatappearwithinexpression[0][y] == Expression[i] && itemsthatappearwithinexpression[1][y] == NOTsNew[i].ToString())
{
matched = true;
break;
}
}
if (!matched)
{
itemsthatappearwithinexpression[0].Add(Expression[i]);
itemsthatappearwithinexpression[1].Add(NOTsNew[i].ToString());
itemsthatappearwithinexpression[2].Add(i.ToString());
}
}
}
for (int x = 0; x < itemsthatappearwithinexpression[0].Count; x++)
{
int occurances = 1;
for (int c = 0; c < Expression.Count; c++)
{
int position = int.Parse(itemsthatappearwithinexpression[2][x]);
if (NOTsNew[c] == NOTsNew[position] && c != position && itemsthatappearwithinexpression[0][x] == Expression[c])
{
occurances++;
}
}
itemsthatappearwithinexpression[3].Add(occurances.ToString());
}
for (int i = 0; i < itemsthatappearwithinexpression[0].Count; i++)
{
if (i < itemsthatappearwithinexpression[0].Count - 1)
{
if (itemsthatappearwithinexpression[3][i] == itemsthatappearwithinexpression[3][i + 1] && int.Parse(itemsthatappearwithinexpression[2][i]) == (int.Parse(itemsthatappearwithinexpression[2][i + 1]) - 2))
{
itemsthatappearwithinexpression[0][i] = itemsthatappearwithinexpression[0][i].ToString() + itemsthatappearwithinexpression[0][i + 1].ToString(); // chars, nots, position, occurances
itemsthatappearwithinexpression[1][i] = itemsthatappearwithinexpression[1][i].ToString() + itemsthatappearwithinexpression[1][i + 1].ToString(); // Nots[0]
itemsthatappearwithinexpression[0].RemoveAt(i + 1);
itemsthatappearwithinexpression[1].RemoveAt(i + 1);
itemsthatappearwithinexpression[2].RemoveAt(i + 1);
itemsthatappearwithinexpression[3].RemoveAt(i + 1);
}
}
}
List<int> positionsoffirstcharinmatches = new List<int>();
string factorisedexpression = "";
bool donextthing = false;
List<int> NOTsinfactorisation = new List<int>();
for (int d = 0; d < itemsthatappearwithinexpression[0].Count; d++)
{
int counter = 0;
bool singularexpansion = false;
if (itemsthatappearwithinexpression[0][d].Length == 1)
{
singularexpansion = true;
}
if (int.Parse(itemsthatappearwithinexpression[3][d]) > 1)
{
for (int i = 0; i < Expression.Count; i++)
{
bool Continue = false;
if (singularexpansion && Expression[i] == itemsthatappearwithinexpression[0][d] && NOTsNew[i] == NOTsNew[int.Parse(itemsthatappearwithinexpression[2][d])])
{
Continue = true;
}
if (i+2 <= Expression.Count-1 && !singularexpansion && Expression[i] == itemsthatappearwithinexpression[0][d][0].ToString() && Expression[i+2] == itemsthatappearwithinexpression[0][d][1].ToString() && NOTsNew[i] == int.Parse(itemsthatappearwithinexpression[1][d][0].ToString()) && NOTsNew[i+2] == int.Parse(itemsthatappearwithinexpression[1][d][1].ToString()))
{
Continue = true;
}
donextthing = false;
if (Continue)
{
if (i != 0)
{
if (Expression[i - 1] == "•")
{
positionsoffirstcharinmatches.Add(i - 2);
if (counter == 0)
{
if (singularexpansion)
{
factorisedexpression += itemsthatappearwithinexpression[0][d] + "•(" + Expression[i - 2] + Expression[i - 3];
NOTsinfactorisation.Add(int.Parse(itemsthatappearwithinexpression[1][d]));
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(NOTsNew[i - 2]);
NOTsinfactorisation.Add(0);
counter++;
}
else
{
positionsoffirstcharinmatches.Add(i);
factorisedexpression += itemsthatappearwithinexpression[0][d][0] + "•" + itemsthatappearwithinexpression[0][d][1] + "•(" + Expression[i - 2] + Expression[i - 3];
//string NOTsOfAdjacentVariables = itemsthatappearwithinexpression[1][d];
NOTsinfactorisation.Add(int.Parse(itemsthatappearwithinexpression[1][d][0].ToString()));
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(int.Parse(itemsthatappearwithinexpression[1][d][1].ToString()));
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(NOTsNew[i - 2]);
NOTsinfactorisation.Add(0);
counter++;
}
}
else
{
if (i >= Expression.Count - 3)
{
factorisedexpression += Expression[i - 2] + ")";
NOTsinfactorisation.Add(NOTsNew[i - 2]);
NOTsinfactorisation.Add(0);
}
else
{
factorisedexpression += Expression[i + 3] + Expression[i + 2];
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(NOTsNew[i + 2]);
}
}
}
else
{
donextthing = true;
}
}
else
{
donextthing = true;
}
if (donextthing)
{
positionsoffirstcharinmatches.Add(i);
if (counter == 0)
{
if (singularexpansion)
{
positionsoffirstcharinmatches.Add(i + 2);
factorisedexpression += itemsthatappearwithinexpression[0][d] + "•(" + Expression[i + 2] + Expression[i + 3];
NOTsinfactorisation.Add(int.Parse(itemsthatappearwithinexpression[1][d]));
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(NOTsNew[i + 2]);
NOTsinfactorisation.Add(0);
counter++;
}
else
{
bool useone = false;
if (Expression[i]+Expression[i+2] == itemsthatappearwithinexpression[0][d] || Expression[i + 2] + Expression[i] == itemsthatappearwithinexpression[0][d])
{
useone = true;
}
positionsoffirstcharinmatches.Add(i+2);
if (useone)
{
factorisedexpression += itemsthatappearwithinexpression[0][d][0] + "•" + itemsthatappearwithinexpression[0][d][1] + "•(" + "1" + Expression[i + 3];
}
else
{
factorisedexpression += itemsthatappearwithinexpression[0][d][0] + "•" + itemsthatappearwithinexpression[0][d][1] + "•(" + Expression[i + 2] + Expression[i + 3];
}
//string NOTsOfAdjacentVariables = itemsthatappearwithinexpression[1][d];
NOTsinfactorisation.Add(int.Parse(itemsthatappearwithinexpression[1][d][0].ToString()));
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(int.Parse(itemsthatappearwithinexpression[1][d][1].ToString()));
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(0);
if (useone)
{
NOTsinfactorisation.Add(0);
}
else
{
NOTsinfactorisation.Add(NOTsNew[i + 2]);
}
NOTsinfactorisation.Add(0);
counter++;
}
}
else
{
if (i == Expression.Count - 3)
{
if (Expression[i]+Expression[i+2] == itemsthatappearwithinexpression[0][d] || Expression[i + 2] + Expression[i] == itemsthatappearwithinexpression[0][d])
{
factorisedexpression += "1" + ")";
NOTsinfactorisation.Add(0);
}
else
{
factorisedexpression += Expression[i + 2] + ")";
NOTsinfactorisation.Add(NOTsNew[i + 2]);
}
NOTsinfactorisation.Add(0);
}
else
{
factorisedexpression += Expression[i + 3] + Expression[i + 2];
NOTsinfactorisation.Add(0);
NOTsinfactorisation.Add(NOTsNew[i + 2]);
}
}
}
}
}
}
else
{
}
}
// character • () --> A•B + A•C Xor A•D = A•(B+C XOR D) - find every instance of the object - get the operator before the object and place the o
//int n = 5; //Expression
positionsoffirstcharinmatches = intbubblesorthightolow(positionsoffirstcharinmatches);
List<int> PositionstoremovefromExpression = new List<int>();
for (int i = 0; i < positionsoffirstcharinmatches.Count; i++)
{
if (positionsoffirstcharinmatches[i] < Expression.Count - 3)
{
PositionstoremovefromExpression.Add(positionsoffirstcharinmatches[i] + 3);
PositionstoremovefromExpression.Add(positionsoffirstcharinmatches[i] + 2);
PositionstoremovefromExpression.Add(positionsoffirstcharinmatches[i] + 1);
PositionstoremovefromExpression.Add(positionsoffirstcharinmatches[i]);
}
else
{
PositionstoremovefromExpression.Add(positionsoffirstcharinmatches[i] + 2);
PositionstoremovefromExpression.Add(positionsoffirstcharinmatches[i] + 1);
PositionstoremovefromExpression.Add(positionsoffirstcharinmatches[i]);
}
}
PositionstoremovefromExpression = intbubblesorthightolow(PositionstoremovefromExpression);
PositionstoremovefromExpression = PositionstoremovefromExpression.Distinct().ToList();
for (int i = 0; i < PositionstoremovefromExpression.Count; i++)
{
NOTsNew.RemoveAt(PositionstoremovefromExpression[i]);
Expression.RemoveAt(PositionstoremovefromExpression[i]); // A • B + C • A
}
for (int i = 0; i < factorisedexpression.Length; i++)
{
try
{
Expression[PositionstoremovefromExpression[PositionstoremovefromExpression.Count - 1] + i] = factorisedexpression[i].ToString();
NOTsNew[PositionstoremovefromExpression[PositionstoremovefromExpression.Count - 1] + i] = NOTsinfactorisation[i];
}
catch (Exception)
{
Expression.Add(factorisedexpression[i].ToString());
NOTsNew.Add(NOTsinfactorisation[i]);
}
}
if (PreviousExpression == convertexpressionlisttostring(Expression))
{
return false;
}
else
{
return true;
}
}
最佳答案
你说:
警告:这是可怕的编程,因为我缺乏经验。
这是正确的。然后你说:
上面的一些代码可以放在子例程中,但我目前正在尝试获取一些工作代码,然后再将其缩短为单独的子例程。
这就是为什么你的代码是可怕的。首先将代码分解为子例程。然后为这些子例程编写测试用例,直到您100%确信该子例程是正确的。你将有一个工具,你可以用来做一个更复杂的程序。
但那只是代码布局。您的基本问题是,您正在编写一个分析器,该分析器在lexer的输出上工作,但您忘记编写解析器。
以下是事情发生的顺序:
您有一个包含表达式的字符串:"A+B•A"
例如。
你写了一本词典。lexer接受一个字符串并生成一个令牌列表。
什么是代币?他们是:
abstract class Token { ... }
sealed class IdentifierToken : Token { ... }
sealed class NotToken : Token { ... }
sealed class OrToken : Token { ... }
sealed class AndToken : Token { ... }
sealed class LeftParenToken : Token { ... }
sealed class RightParenToken : Token { ... }
sealed class TrueToken : Token { ... }
sealed class FalseToken : Token { ... }
public static List<Token> Lexer(string s) { ... }
abstract class ParseNode { ... }
sealed class OrNode : ParseNode
{
public ParseNode Left { get; }
public ParseNode Right { get; }
...
// Or maybe IEnumerable<ParseNode> Children { get; }
// is easier; both techniques have their strengths.
}
sealed class AndNode : ParseNode { ... }
sealed class NotNode : ParseNode { ... }
sealed class IdentifierNode : ParseNode { ... }
sealed class TrueNode : ParseNode { ... }
sealed class FalseNode : ParseNode { ... }
"(A+~B)*C"
,那么lexer会说
LPAREN, IDENTIFIER(A), OR, NOT, IDENTIFIER(B), RPAREN, AND, IDENTIFIER(C)
。然后解析器从lexer获取列表并生成
And
/ \
Or Id(C)
/ \
Id(A) Not
|
Id(B)
public static ParseNode Parser(List<Token> tokens) { ... }
A+B*C
解析为
A+(B*C)
而不是
(A+B)*C
。它将有助于为正在解析的语言编写一个正式的、明确的上下文无关语法。举个例子,我想这句话很清楚地说明了:
EXPR : OREX
OREX : ANDEX ORTAIL
ORTAIL : NIL
ORTAIL : + ANDEX ORTAIL
ANDEX : NOTEX ANDTAIL
ANDTAIL : NIL
ANDTAIL : * NOTEX ANDTAIL
NOTEX : CONST
NOTEX : ( EXPR )
NOTEX : ~ NOTEX
NOTEX : IDENT
IDENT : <any single letter>
CONST : 1
CONST : 0
Not -> True
可以替换为
False
,反之亦然
Not -> Not -> anything
,可替换为
anything
Or
左侧或右侧的
True
可替换为
True
Or
左边的
False
可以被右边的替换。
And
两边都有
False
是
False
public static ParseNode FooOptimization(ParseNode p) { ... }
public static ParseNode BarOptimization(ParseNode p) { ... }
public static ParseNode NotFalseOptimization(ParseNode p)
{
if (p is NotNode n)
{
// The child might itself have a Not(False) somewhere in it.
ParseNode child = NotFalseOptimization(n.Child);
if (child is FalseNode)
return new TrueNode();
else
return new NotNode(child);
}
else if (p is OrNode o)
return new OrNode(NotFalseOptimization(o.Left), NotFalseOptimization(o.Right);
else if (p is AndNode a)
return new AndNode(NotFalseOptimization(a.Left), NotFalseOptimization(a.Right);
else
return p;
}
ToString
上执行
ParseNode
。
static string DoItAll(string s)
{
var tokens = Lex(s);
var tree = Parse(tokens);
var optimized = Optimize(tree);
return optimized.ToString();
}
关于c# - bool 代数表达式分解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54680280/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!