将逻辑表达式转化为阈值形式

在ABE(基于属性的加密)中,访问控制树可以分为两种,其中一种为AND/OR组成的逻辑表达式,还有就是用阈值表示的形式。如:A OR(B AND C)这种。转化为阈值就是B C 2/2 A 1/2,意思就是B和C必须满足一个并且要满足A。下面两个树状图分别代表阈值和逻辑表达式的结构。因为实验的需要,今天主要是描述如何将逻辑表达式转化为阈值形式(例如A OR(B AND C)转化为B C 2/2 A 1/2)。

这里是用Java进行编程:

这里我们先分析一下:要做的工作主要分为三个函数,其中第三个步骤将调用前两个函数。

  1. 将字符串转化为单词数组,如:String={"A AND B AND C"} ——>  List<String>={"A","AND","B","AND","C"}。意思是要将一串字符串进行分解。
  2. 将单词转化为阈值形式,如:List<String>={"A","AND","B","AND","C"} ——>   String={"C B A 3of3"},我们将不含括号的一个逻辑表达式转换为阈值形式。
  3. 将逻辑表达式转化为阈值表达式:如:String={"D OR ( A AND ( B AND C AND E ) )"}  ——> String={"E C B 3of3 A 2of2 D 1of2"},这个就是最终在主函数中调用的函数。这里将用到栈。

前面两个都很好编写。主要是最后一个,需要用到栈相关知识。那么这里简要阐述一下算法。当输出不为")"时,入栈。否则,出栈,直到遇到与")"匹配的"("。

还是举一个例子来说明,比较好理解。

假如我们输入的是D OR ( A AND ( F OR ( B AND C AND E ) ) ),步骤如下:

  1. 申请一个栈,简称为stack
  2. 首先判断输入字符串是否为")",如果不是则入栈。如:D OR ( A AND ( F OR ( B AND C AND E都依次入栈。
  3. 否则,将")"所匹配的"("之前的所有字符出栈,转化为一个逻辑表达式。如:当E入栈后,下一个即将入栈字符串为")",于是将B AND C AND E出栈,转化为E C B 3/3。然后删除现在栈顶的"("。将"E C B 3/3"入栈。继续上述步骤。下一个输入的又是")"于是将"E C B 3/3"出栈, OR,F出栈。删除现在栈顶的"(",将这三个字符串转化为E C B 3/3 F 1/2。并且入栈。继续,下一个输入的还是")",于是"E C B 3/3 F 1/2"出栈,AND,A出栈。删除现在栈顶的"(",将这三个字符串转化为E C B 3/3 F 1/2 A 2/2。并入栈。
  4. 检查stack是否为空,若是则结束,若不是,则将栈内元素出栈。如:将"E C B 3/3 F 1/2 A 2/2"出栈,OR,D出栈。将三个字符串转化为E C B 3/3 F 1/2 A 2/2 D 1/2。至此,转化完成。

现在附上代码:

package transform;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Transform {
	/**
	 * 此函数是将字符串转化为单词数组,如:
	 * String={"A AND B AND C"} ——>  List<String>={"A","AND","B","AND","C"}
	 * @param A
	 * @return List<String>
	 */
	public List<String> stringToList(String A) {
		List<String> predicate = new ArrayList<String>();
		int beginIndex = 0;
		for (int endIndex = 0; endIndex < A.length(); endIndex++) {
			if (A.charAt(endIndex) != ' ') {
				continue;
			} else {
				// System.out.println(beginIndex + " " + endIndex);
				predicate.add(A.substring(beginIndex, endIndex));
				beginIndex = endIndex + 1;
				endIndex += 1;
			}
		}
		predicate.add(A.substring(beginIndex));
		return predicate;
	}

	/**
	 * 将单词转化为阈值形式,如:
	 * List<String>={"A","AND","B","AND","C"}  ——>   String={"C B A 3of3"}
	 * @param lStr
	 * @return String
	 */
	public String pTog(List<String> lStr) {
		int andIndex = 0;
		int orIndex = 0;
		for (int i = 0; i < lStr.size(); i++) {
			if (lStr.get(i).equals("AND")) {
				andIndex++;
				lStr.remove(i);
				i--;
			}
			if (lStr.get(i).equals("OR")) {
				orIndex++;
				lStr.remove(i);
				i--;
			}
		}
		// System.out.println(andIndex);
		// System.out.println("------------------------");
		// for (String x : lStr) {
		// System.out.println(x);
		// }
		if (andIndex > 0) {
			lStr.add((andIndex + 1) + "of" + (andIndex + 1));
		}
		if (orIndex > 0) {
			lStr.add(1 + "of" + (orIndex + 1));
		}
		String str = new String();
		for (String x : lStr) {
			str = str.concat(x + " ");
		}
		
		// System.out.println(str);
		str = str.substring(0,str.length() - 1);//删除末尾空格
		return str;
	}
	/**
	 * 此函数是将逻辑表达式转化为阈值表达式:如:
	 * String={"D OR ( A AND ( B AND C AND E ) )"}  ——> String={"E C B 3of3 A 2of2 D 1of2"}
	 * @param A
	 * @return String
	 */
	public String transStack(String A) {
		List<String> predicate = stringToList(A);
		Stack<String> letter = new Stack<String>();
		List<String> thresholdTemp=new ArrayList<String>();
		
		int i = 0;
		while (i < predicate.size()) {
			if (!predicate.get(i).equals(")")) {
				letter.push(predicate.get(i));
				System.out.println("入栈:"+predicate.get(i));
			}else{//即将要进栈栈顶元素为")"时
				while(!letter.peek().equals("(")){//当没碰到"("时出栈,并放到thresholdTemp中
					System.out.println("出栈:"+letter.peek());
					thresholdTemp.add(letter.pop());
				}
				String tempLetter=pTog(thresholdTemp);
				System.out.println(tempLetter);
				thresholdTemp.clear();
				letter.pop();//将"("移出栈
				letter.push(tempLetter);
				System.out.println("入栈:"+tempLetter);
			}
			i++;
		}
		while(!letter.empty()){
			thresholdTemp.add(letter.pop());
		}
		String tempLetter=pTog(thresholdTemp);
		return tempLetter;
	}
}

现在写出一个测试类进行测试:

package transform;
public class TransformTest {

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		String A="D OR ( A AND ( F OR ( B AND C AND E ) ) )";
		Transform trans=new Transform();
		String G=trans.transStack(A);
		System.out.println(G);
	}

}

控制台显示输出为:

输出结果为正确的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值